文章目录1. 区块的基本组成1.1 为什么要分成区块头和区块体2. 区块头 Header 详解2.1 Version版本号2.2 Prev-block Hash前一区块哈希2.3 Merkle-root交易集合的总摘要2.4 Timestamp时间戳2.5 Bits难度目标2.6 Nonce随机数2.7 小例子工作量证明如何体现“难”3. 区块体 Body 详解4. 链式结构区块为什么能连成链4.1 链式结构的形成过程4.2 为什么链式结构能防篡改4.3 完整副本是什么意思5. 哈希列表与二叉树5.1 Hash List哈希列表5.2 Binary Tree二叉树6. 默克尔树 Merkle Tree6.1 Merkle Tree 的构造过程6.2 如果交易数量是奇数怎么办6.3 Coinbase 交易是什么6.4 Merkle Proof如何证明某笔交易在区块中6.5 Merkle Tree 的优势7. 以太坊中的 MPTMerkle Patricia Tree7.1 为什么以太坊需要 MPT7.2 Trie 树是什么7.3 Patricia Tree 是什么7.4 Merkle Patricia Trie 的结合7.5 MPT 中的节点类型7.6 MPT 中 key 和 value 是什么7.7 以太坊区块中的三棵树7.8 为什么说状态 MPT 会不断更新7.9 MPT 能支持哪些查询8. SPV简化支付验证8.1 SPV 解决什么问题8.2 SPV 验证的是“支付”不是完整交易合法性8.3 SPV 的验证思路8.4 举例如何判断一笔交易有 6 个确认9. 布隆过滤器 Bloom Filter9.1 布隆过滤器能回答什么问题9.2 布隆过滤器的基本原理9.3 为什么会出现误判9.4 布隆过滤器在 SPV 中的作用9.5 例题查找过去 10 天与某智能合约相关的交易情况一完整节点情况二轻节点 / SPV 思路情况三以太坊场景10. 综合例题与答疑10.1 例题一为什么修改一笔交易会影响区块哈希10.2 例题二区块头为什么不直接保存所有交易10.3 例题三SPV 能不能发现双花10.4 例题四Merkle Tree 和 MPT 有什么区别10.5 例题五布隆过滤器为什么不能删除元素11. 复习速记表11.1 区块结构速记11.2 树结构速记11.3 高频问答Q1区块链为什么难以篡改Q2Merkle-root 的核心意义是什么Q3SPV 节点保存什么Q4Bloom Filter 的判断结果怎么理解Q5以太坊为什么要用 MPT12. 一页总结1. 区块的基本组成区块链中的每一个区块通常由两大部分组成区块 Block ├── 区块头 Header存放用于连接、校验、共识、索引的元数据 └── 区块体 Body存放本区块打包的交易数据也可以把区块理解为一本账本中的“一页”区块头像这一页账本的页眉记录版本号、上一页编号、摘要、时间等信息区块体像这一页账本的正文记录实际发生的交易前一区块哈希像页码引用使每一页都能按顺序连接起来Merkle-root像本页所有交易内容的总摘要用于快速证明某笔交易是否在这个区块中。1.1 为什么要分成区块头和区块体区块头和区块体的分离可以同时兼顾两类需求需求对应结构作用快速验证区块是否有效区块头区块头很小便于传播、存储和验证保存真实交易记录区块体存放完整交易信息轻节点验证交易区块头 Merkle proof不下载完整区块体也能验证交易存在性防篡改前一区块哈希 Merkle-root改一笔交易会影响 Merkle-root进一步影响区块哈希**一句话总结**区块头负责“证明和连接”区块体负责“记录和承载”。2. 区块头 Header 详解区块头是区块中非常核心的部分。以比特币为例一个区块头通常包含以下字段字段常见大小作用Version4 Byte当前区块使用的软件/协议版本Prev-block Hash32 Byte前一区块的哈希值用来把区块串成链Merkle-root32 Byte本区块所有交易经过 Merkle Tree 计算后的根哈希Timestamp4 Byte区块生成的大致时间Bits4 Byte当前工作量证明的目标难度压缩表示Nonce4 Byte挖矿时不断调整的随机数2.1 Version版本号Version表示区块遵循的协议规则或软件版本。区块链系统不断升级时需要通过版本号识别区块使用的规则。例子如果一次协议升级引入了新的交易验证规则新节点可以通过区块头中的版本号判断Version 1旧规则 Version 2新规则这有点像软件版本旧版软件可能不支持新版文件格式。2.2 Prev-block Hash前一区块哈希Prev-block Hash是区块链形成“链”的关键。每个区块头中都保存前一个区块的哈希值。Block 1 Hash → 写入 Block 2 的 Prev-block Hash Block 2 Hash → 写入 Block 3 的 Prev-block Hash Block 3 Hash → 写入 Block 4 的 Prev-block Hash如果有人修改了 Block 2 的内容Block 2 的哈希就会改变那么 Block 3 中记录的Prev-block Hash就对不上整条链都会暴露异常。2.3 Merkle-root交易集合的总摘要Merkle-root是区块体内所有交易的摘要结果。它不是直接把交易全部写进区块头而是先把交易组织成 Merkle Tree再把根节点哈希放到区块头里。作用让区块头保持很小快速证明某笔交易是否属于某区块任意一笔交易被篡改Merkle-root 都会变化支持 SPV 轻节点验证。2.4 Timestamp时间戳Timestamp表示区块生成的大致时间。它可以帮助节点判断区块顺序也能辅助难度调整。需要注意的是区块时间戳不是普通意义上的精确服务器时间而是链上节点接受范围内的近似时间。2.5 Bits难度目标Bits是工作量证明目标难度的压缩表示。矿工需要不断改变 Nonce使区块头哈希满足难度要求。简化理解难度越高 → 目标值越小 → 找到合格哈希越难 难度越低 → 目标值越大 → 找到合格哈希越容易2.6 Nonce随机数Nonce是矿工挖矿时反复尝试的数。矿工不断改变 Nonce然后计算区块头哈希直到得到符合 Bits 难度要求的哈希。简化过程如下区块头 Version PrevHash MerkleRoot Timestamp Bits Nonce Hash SHA256(SHA256(区块头)) 如果 Hash 目标难度挖矿成功 否则Nonce 1 后继续尝试2.7 小例子工作量证明如何体现“难”假设要求哈希值必须以 4 个 0 开头0000a34f... 合格 00f19b3c... 不合格 1a04bccc... 不合格矿工并不能直接“设计”一个合格哈希只能不断改变 Nonce 试出来。因此Nonce 可以理解为“试题答案草稿纸上的不断尝试”。3. 区块体 Body 详解区块体主要保存交易数据。不同区块链系统中区块体的组织方式不同但共同点是它承载的是链上真正发生的业务数据。在比特币中区块体主要是交易列表区块体 Body ├── 交易数量 ├── 交易 1 ├── 交易 2 ├── 交易 3 └── ...在以太坊中区块不仅要记录交易还要记录状态变化、收据等信息因此以太坊区块头中会保存多棵树的根哈希例如transaction root交易树根state root状态树根receipt root收据树根。区块体越大完整节点存储和同步压力越大区块头越小轻节点验证越方便。4. 链式结构区块为什么能连成链区块链是一个按照区块生成时间顺序连接形成的分布式数据库。连接的关键就是区块头中的Prev-block Hash字段。4.1 链式结构的形成过程假设有三个区块Block A Hash(A) aaa111 Block B Prev-block Hash aaa111 Hash(B) bbb222 Block C Prev-block Hash bbb222 Hash(C) ccc333最终结构为Block A ← Block B ← Block C aaa111 bbb222 ccc333其中Block B 的区块头记录了 Block A 的哈希Block C 的区块头记录了 Block B 的哈希。4.2 为什么链式结构能防篡改如果攻击者修改 Block A 中的一笔交易交易内容变化Block A 的 Merkle-root 变化Block A 的区块头变化Block A 的 Hash 变化Block B 中保存的 Prev-block Hash 与新 Hash 对不上攻击者必须继续修改 Block B、Block C 以及后续所有区块还要重新完成这些区块的工作量证明。因此越早的区块越难篡改因为后面叠加的区块越多需要重做的计算量越大。4.3 完整副本是什么意思PPT 中提到“形成了区块链表也形成了一个完整的账本”。意思是每个完整节点可以保存从创世区块到当前区块的全部数据节点之间可以互相校验数据是否一致任意节点不需要完全信任单个中心服务器而是通过密码学哈希和共识规则验证账本。5. 哈希列表与二叉树PPT 中对比了 Hash list 和 Binary tree。5.1 Hash List哈希列表Hash List 的基本思想是对每个数据块分别计算哈希然后再把这些哈希组合成一个根哈希。DATA 0 → HASH 0 DATA 1 → HASH 1 DATA 2 → HASH 2 ... DATA n → HASH n HASH 0 HASH 1 ... HASH n → HASH root缺点是如果要证明某个数据在列表中可能需要较多数据辅助验证。5.2 Binary Tree二叉树二叉树是一种每个节点最多有两个子节点的数据结构。Merkle Tree 就是一种典型的哈希二叉树。在 Merkle Tree 中叶子节点通常是交易哈希非叶子节点是左右子节点哈希拼接后再哈希根节点是整棵树的摘要。6. 默克尔树 Merkle TreeMerkle Tree 是区块链中非常重要的数据结构。它的核心目标是用一个根哈希代表大量交易并支持高效的交易存在性证明。6.1 Merkle Tree 的构造过程假设一个区块中包含 4 笔交易Tx1, Tx2, Tx3, Tx4第一步计算每笔交易的哈希。H1 Hash(Tx1) H2 Hash(Tx2) H3 Hash(Tx3) H4 Hash(Tx4)第二步两两组合再哈希。H12 Hash(H1 || H2) H34 Hash(H3 || H4)第三步继续组合到根节点。MerkleRoot Hash(H12 || H34)整体结构MerkleRoot / \ H12 H34 / \ / \ H1 H2 H3 H4 | | | | Tx1 Tx2 Tx3 Tx4其中||表示拼接。6.2 如果交易数量是奇数怎么办如果交易数量是奇数常见做法是复制最后一个哈希使其变成偶数个再继续计算。例如有 5 笔交易H1, H2, H3, H4, H5可以处理为H1, H2, H3, H4, H5, H5然后两两组合。6.3 Coinbase 交易是什么PPT 中提到 Coinbase 交易。它不是交易所 Coinbase而是比特币区块中的特殊交易。Coinbase 交易的作用通常是区块中的第一笔交易用来给矿工发放区块奖励和手续费没有普通交易那样引用前一笔 UTXO也会参与 Merkle Tree 的计算。6.4 Merkle Proof如何证明某笔交易在区块中假设要证明Tx3在区块中。完整节点不需要把所有交易都发给轻节点只需要发送验证路径上的相邻哈希已知Tx3 需要H4、H12、MerkleRoot 验证 H3 Hash(Tx3) H34 Hash(H3 || H4) Root Hash(H12 || H34) 判断 Root 是否等于区块头中的 MerkleRoot如果相等就能证明 Tx3 确实属于该区块。6.5 Merkle Tree 的优势优势解释高效验证不需要下载全部交易只需下载一条验证路径防篡改任意交易变化都会导致 Merkle-root 改变节省空间区块头只保存一个根哈希支持轻节点SPV 可以基于 Merkle Proof 验证交易存在性7. 以太坊中的 MPTMerkle Patricia TreePPT 中介绍了以太坊使用的 MPT即 Merkle Patricia Tree也称默克尔帕特里夏树。7.1 为什么以太坊需要 MPT比特币主要关注交易是否存在、UTXO 是否可花费而以太坊不只是转账系统它还要支持账户余额合约代码合约存储交易执行后的状态变化收据和日志。因此以太坊需要一种能够同时支持哈希校验快速查找状态更新空间压缩轻客户端证明的数据结构。MPT 就是为此设计的。7.2 Trie 树是什么Trie 树又称字典树、前缀树适合存储字符串或键值数据。Trie 树的特点根节点通常不包含字符从根节点到某节点的路径表示一个字符串前缀公共前缀可以共享适合文本检索、自动补全、字典匹配等场景。例如要存储三个词cat car dog可以共享ca前缀root / \ c d | | a o / \ | t r g7.3 Patricia Tree 是什么Patricia Tree 可以看作对 Trie 的压缩。普通 Trie 可能出现很多“只有一个子节点”的节点浪费空间。Patricia Tree 会压缩这些单分支路径。例如普通 Trie root → a → b → c → d Patricia 压缩后 root → abcd这样可以减少节点数量降低存储成本。7.4 Merkle Patricia Trie 的结合MPT 可以理解为三种思想的组合结构提供能力Merkle每个节点有哈希可验证、防篡改Patricia压缩路径节省空间Trie按 key 的路径查找适合键值存储所以 MPT 不是普通树而是具有密码学验证能力的压缩前缀树。7.5 MPT 中的节点类型PPT 中提到为了降低树高、降低操作复杂度MPT 引入了几类节点节点类型作用空节点表示空字符串或不存在的节点扩展节点 Extension Node压缩公共路径分支节点 Branch Node表示路径分叉通常有 16 个分支叶子节点 Leaf Node保存最终的 key-value 数据7.6 MPT 中 key 和 value 是什么在以太坊状态树中key 账户地址经过编码后的路径 value 账户状态信息账户状态可能包括nonce账户交易次数balance账户余额storageRoot合约存储树根codeHash合约代码哈希。在交易树中key 交易在区块中的序号 value 交易内容在收据树中key 交易在区块中的序号 value 交易执行后的收据信息7.7 以太坊区块中的三棵树PPT 中提到以太坊区块中包含交易、收据和状态三类树树区块头中的根主要用途交易 MPTtransaction root证明某笔交易是否在该区块中收据 MPTreceipt root证明交易执行结果、日志、事件是否存在状态 MPTstate root证明某个账户余额、合约状态等全局状态7.8 为什么说状态 MPT 会不断更新以太坊是账户模型。每笔交易执行后都可能改变账户余额、合约状态或 nonce。例如Alice 向 Bob 转账 1 ETH执行后Alice 余额减少 Bob 余额增加 Alice nonce 增加 状态树更新 state root 改变这就是为什么每个以太坊区块头都要记录新的state root。7.9 MPT 能支持哪些查询PPT 中列出了轻客户端可以实现的查询。整理如下查询问题由哪棵树处理这笔交易是否包含在某个区块中交易 MPT某地址过去 30 天内发出某类事件的所有实例收据 MPT某账户当前余额是多少状态 MPT某账户是否存在状态 MPT某合约交易的输出是什么状态 MPT 收据 MPT8. SPV简化支付验证SPV 的英文全称是 Simplified Payment Verification中文通常称为“简化支付验证”。8.1 SPV 解决什么问题完整节点需要保存完整区块数据数据量很大。对于手机钱包、物联网设备等资源有限的终端来说保存完整区块链不现实。SPV 的目标是不下载完整区块体只保存区块头也能验证某笔交易是否已经被区块链网络确认。8.2 SPV 验证的是“支付”不是完整交易合法性PPT 中特别强调SPV 技术的设计目标是验证“支付”而不是验证“交易”。这句话非常重要。交易验证需要检查签名、余额是否足够、是否双花、脚本是否合法等支付验证只验证某笔交易是否已经出现在某个区块中并且后面有足够确认数。换句话说SPV 用户不能像完整节点一样独立验证所有共识规则它主要依赖区块头链Merkle Proof网络中多数算力选择的最长有效链。8.3 SPV 的验证思路SPV 节点验证交易的大致流程SPV 钱包只同步区块头当用户关心某笔交易时向完整节点请求相关证明完整节点返回包含该交易的区块头该交易的 Merkle Proof该区块之后的区块头链SPV 节点利用 Merkle Proof 验证交易属于该区块再检查该区块后面有多少确认数确认数足够时认为支付可信。8.4 举例如何判断一笔交易有 6 个确认假设交易Tx100被打包进区块高度 1000。当前最长链高度为 10061000 → 1001 → 1002 → 1003 → 1004 → 1005 → 1006那么Tx100所在区块后面已经追加了 6 个区块通常可以说它有 6 个确认。注意不同系统、不同金额、不同风险场景对确认数要求不同。9. 布隆过滤器 Bloom Filter布隆过滤器是一种空间效率很高的概率型数据结构。它可以用来判断一个元素是否可能属于某集合。9.1 布隆过滤器能回答什么问题布隆过滤器回答的问题是某元素是否在集合中但它的回答有两个特点回答含义一定不在结果可靠可能在可能是真的也可能是假阳性PPT 中强调布隆过滤器不能完全确定一定在一个集合内 而不能完全确定一定在一个集合内。更准确地说布隆过滤器可以准确判断“不存在”但不能百分百确认“存在”。9.2 布隆过滤器的基本原理布隆过滤器由一个位数组和多个哈希函数组成。假设位数组初始全为 0位置0 1 2 3 4 5 6 7 8 9 值 0 0 0 0 0 0 0 0 0 0插入元素X时用多个哈希函数计算位置H1(X) 2 H2(X) 5 H3(X) 7把对应位置置为 1位置0 1 2 3 4 5 6 7 8 9 值 0 0 1 0 0 1 0 1 0 0查询元素Y时如果它对应的某个位置为 0就说明它一定不在集合中。如果所有位置都是 1只能说明它“可能在集合中”。9.3 为什么会出现误判因为不同元素可能通过哈希函数映射到相同位置。例如X 设置了位置 2、5、7 Z 设置了位置 1、5、8查询 Y 时假设 Y 对应位置刚好是2、5、8虽然 Y 没有插入过但这些位置已经被其他元素置为 1于是布隆过滤器会说Y 可能在集合中这就是假阳性。9.4 布隆过滤器在 SPV 中的作用SPV 钱包如果直接向网络询问请告诉我和地址 A 有关的所有交易就会暴露隐私因为对方知道这个钱包关心地址 A。布隆过滤器可以让 SPV 节点发送一个“模糊条件”请把可能和我有关的交易发给我完整节点根据 Bloom Filter 过滤区块中的交易把可能相关的数据返回给 SPV 节点。这样可以减少无关数据下载提高查询效率一定程度保护隐私但不能完全保护隐私因为过滤模式仍可能被分析。9.5 例题查找过去 10 天与某智能合约相关的交易PPT 中的问题是要查找过去 10 天发生的所有和这个智能合约相关的交易怎么找可以分场景回答。情况一完整节点完整节点保存完整区块和状态可以直接遍历过去 10 天内的区块1. 找到过去 10 天对应的区块高度范围 2. 遍历这些区块中的交易 3. 筛选 to/from 地址等于目标合约地址的交易 4. 如果需要事件日志再读取交易收据 logs 5. 汇总结果情况二轻节点 / SPV 思路轻节点不保存完整交易数据可以1. 保存或同步区块头 2. 向完整节点请求与合约地址相关的交易/收据证明 3. 使用 Merkle Proof 或 MPT Proof 验证返回结果 4. 根据区块高度或时间戳限定过去 10 天情况三以太坊场景以太坊中不仅要找交易还可能要找合约事件。交易是否存在交易 MPT 交易执行结果和事件日志收据 MPT 合约当前状态状态 MPT如果只是找“调用该合约的交易”主要看交易中的to字段如果要找“合约发出的事件”则主要看 receipt logs。10. 综合例题与答疑10.1 例题一为什么修改一笔交易会影响区块哈希**问题**某区块中一笔交易被篡改为什么区块哈希会变化答案交易变化 → 交易哈希变化 → Merkle Tree 中相关父节点哈希变化 → Merkle-root 变化 → 区块头变化 → 区块哈希变化因为区块头中保存了 Merkle-root所以区块体中的交易变化最终会传导到区块头哈希。10.2 例题二区块头为什么不直接保存所有交易因为交易数量可能很多直接把交易全部塞进区块头会导致区块头巨大不利于传播和轻节点验证。使用 Merkle-root 后区块头只需保存一个 32 字节左右的根哈希就能代表整个交易集合。10.3 例题三SPV 能不能发现双花SPV 不能像完整节点一样独立检查所有双花情况。它主要通过交易是否被打包进区块区块是否属于最长链后续确认数是否足够来降低双花风险。因此SPV 是一种轻量级验证方案安全性依赖网络中诚实算力和完整节点返回的证明。10.4 例题四Merkle Tree 和 MPT 有什么区别对比项Merkle TreeMPT主要应用比特币交易集合证明以太坊账户、交易、收据证明结构哈希二叉树压缩前缀树 Merkle 哈希查询方式根据交易哈希验证存在性根据 key 路径查找 value是否适合频繁状态更新一般更适合典型根哈希Merkle-rootstate root / tx root / receipt root10.5 例题五布隆过滤器为什么不能删除元素普通布隆过滤器中一个位置可能被多个元素共同设置为 1。如果删除某个元素时把对应位置改回 0可能会误删其他元素的标记导致原本存在的元素被判断为不存在。因此普通 Bloom Filter 不支持安全删除。若要支持删除需要使用 Counting Bloom Filter 等变体。11. 复习速记表11.1 区块结构速记概念速记区块区块头 区块体区块头连接区块、验证区块、支持共识区块体保存交易数据Prev-block Hash指向前一区块形成链Merkle-root本区块所有交易的总摘要Nonce挖矿时不断尝试的随机数Bits难度目标压缩表示11.2 树结构速记数据结构关键词主要用途Hash List顺序哈希简单数据摘要Binary Tree左右子树Merkle Tree 基础结构Merkle Tree根哈希、验证路径交易存在性证明Trie前缀共享字符串/键值检索Patricia Tree路径压缩节省空间MPTMerkle Patricia Trie以太坊状态、交易、收据证明Bloom Filter一定不在、可能在高效集合过滤11.3 高频问答Q1区块链为什么难以篡改因为每个区块都包含前一区块哈希且交易数据通过 Merkle-root 写入区块头。修改历史交易会导致 Merkle-root 和区块哈希变化还会破坏后续区块的链接攻击者必须重算后续所有区块的工作量证明。Q2Merkle-root 的核心意义是什么用一个根哈希代表整个交易集合并支持高效验证某笔交易是否属于该区块。Q3SPV 节点保存什么主要保存区块头不保存完整区块体。需要验证某笔交易时再向完整节点请求 Merkle Proof。Q4Bloom Filter 的判断结果怎么理解返回“不在”一定不在返回“可能在”可能在也可能是误判。Q5以太坊为什么要用 MPT因为以太坊不仅要记录交易还要维护账户状态、合约状态、交易收据等复杂键值数据。MPT 同时具备快速查找、路径压缩和哈希证明能力。12. 一页总结区块链的区块结构可以概括为区块 区块头 区块体 区块头 Version PrevHash MerkleRoot Timestamp Bits Nonce 区块体 交易列表 / 状态变化相关数据区块通过Prev-block Hash首尾相连形成不可轻易篡改的链式账本交易通过 Merkle Tree 形成 Merkle-root写入区块头实现交易集合的高效摘要和存在性证明轻节点通过 SPV 只保存区块头并借助 Merkle Proof 验证支付是否存在以太坊进一步使用 MPT 管理交易、收据和账户状态使复杂的智能合约系统也能实现可验证的数据查询Bloom Filter 则用于高效过滤可能相关的数据降低轻节点的数据下载压力。最终理解区块结构的本质不是简单“存数据”而是通过哈希、树结构和链式引用把数据组织成一个可验证、可追溯、难篡改、可分布式维护的账本系统。
区块链原理与技术02:区块链的数据结构04(区块结构)
文章目录1. 区块的基本组成1.1 为什么要分成区块头和区块体2. 区块头 Header 详解2.1 Version版本号2.2 Prev-block Hash前一区块哈希2.3 Merkle-root交易集合的总摘要2.4 Timestamp时间戳2.5 Bits难度目标2.6 Nonce随机数2.7 小例子工作量证明如何体现“难”3. 区块体 Body 详解4. 链式结构区块为什么能连成链4.1 链式结构的形成过程4.2 为什么链式结构能防篡改4.3 完整副本是什么意思5. 哈希列表与二叉树5.1 Hash List哈希列表5.2 Binary Tree二叉树6. 默克尔树 Merkle Tree6.1 Merkle Tree 的构造过程6.2 如果交易数量是奇数怎么办6.3 Coinbase 交易是什么6.4 Merkle Proof如何证明某笔交易在区块中6.5 Merkle Tree 的优势7. 以太坊中的 MPTMerkle Patricia Tree7.1 为什么以太坊需要 MPT7.2 Trie 树是什么7.3 Patricia Tree 是什么7.4 Merkle Patricia Trie 的结合7.5 MPT 中的节点类型7.6 MPT 中 key 和 value 是什么7.7 以太坊区块中的三棵树7.8 为什么说状态 MPT 会不断更新7.9 MPT 能支持哪些查询8. SPV简化支付验证8.1 SPV 解决什么问题8.2 SPV 验证的是“支付”不是完整交易合法性8.3 SPV 的验证思路8.4 举例如何判断一笔交易有 6 个确认9. 布隆过滤器 Bloom Filter9.1 布隆过滤器能回答什么问题9.2 布隆过滤器的基本原理9.3 为什么会出现误判9.4 布隆过滤器在 SPV 中的作用9.5 例题查找过去 10 天与某智能合约相关的交易情况一完整节点情况二轻节点 / SPV 思路情况三以太坊场景10. 综合例题与答疑10.1 例题一为什么修改一笔交易会影响区块哈希10.2 例题二区块头为什么不直接保存所有交易10.3 例题三SPV 能不能发现双花10.4 例题四Merkle Tree 和 MPT 有什么区别10.5 例题五布隆过滤器为什么不能删除元素11. 复习速记表11.1 区块结构速记11.2 树结构速记11.3 高频问答Q1区块链为什么难以篡改Q2Merkle-root 的核心意义是什么Q3SPV 节点保存什么Q4Bloom Filter 的判断结果怎么理解Q5以太坊为什么要用 MPT12. 一页总结1. 区块的基本组成区块链中的每一个区块通常由两大部分组成区块 Block ├── 区块头 Header存放用于连接、校验、共识、索引的元数据 └── 区块体 Body存放本区块打包的交易数据也可以把区块理解为一本账本中的“一页”区块头像这一页账本的页眉记录版本号、上一页编号、摘要、时间等信息区块体像这一页账本的正文记录实际发生的交易前一区块哈希像页码引用使每一页都能按顺序连接起来Merkle-root像本页所有交易内容的总摘要用于快速证明某笔交易是否在这个区块中。1.1 为什么要分成区块头和区块体区块头和区块体的分离可以同时兼顾两类需求需求对应结构作用快速验证区块是否有效区块头区块头很小便于传播、存储和验证保存真实交易记录区块体存放完整交易信息轻节点验证交易区块头 Merkle proof不下载完整区块体也能验证交易存在性防篡改前一区块哈希 Merkle-root改一笔交易会影响 Merkle-root进一步影响区块哈希**一句话总结**区块头负责“证明和连接”区块体负责“记录和承载”。2. 区块头 Header 详解区块头是区块中非常核心的部分。以比特币为例一个区块头通常包含以下字段字段常见大小作用Version4 Byte当前区块使用的软件/协议版本Prev-block Hash32 Byte前一区块的哈希值用来把区块串成链Merkle-root32 Byte本区块所有交易经过 Merkle Tree 计算后的根哈希Timestamp4 Byte区块生成的大致时间Bits4 Byte当前工作量证明的目标难度压缩表示Nonce4 Byte挖矿时不断调整的随机数2.1 Version版本号Version表示区块遵循的协议规则或软件版本。区块链系统不断升级时需要通过版本号识别区块使用的规则。例子如果一次协议升级引入了新的交易验证规则新节点可以通过区块头中的版本号判断Version 1旧规则 Version 2新规则这有点像软件版本旧版软件可能不支持新版文件格式。2.2 Prev-block Hash前一区块哈希Prev-block Hash是区块链形成“链”的关键。每个区块头中都保存前一个区块的哈希值。Block 1 Hash → 写入 Block 2 的 Prev-block Hash Block 2 Hash → 写入 Block 3 的 Prev-block Hash Block 3 Hash → 写入 Block 4 的 Prev-block Hash如果有人修改了 Block 2 的内容Block 2 的哈希就会改变那么 Block 3 中记录的Prev-block Hash就对不上整条链都会暴露异常。2.3 Merkle-root交易集合的总摘要Merkle-root是区块体内所有交易的摘要结果。它不是直接把交易全部写进区块头而是先把交易组织成 Merkle Tree再把根节点哈希放到区块头里。作用让区块头保持很小快速证明某笔交易是否属于某区块任意一笔交易被篡改Merkle-root 都会变化支持 SPV 轻节点验证。2.4 Timestamp时间戳Timestamp表示区块生成的大致时间。它可以帮助节点判断区块顺序也能辅助难度调整。需要注意的是区块时间戳不是普通意义上的精确服务器时间而是链上节点接受范围内的近似时间。2.5 Bits难度目标Bits是工作量证明目标难度的压缩表示。矿工需要不断改变 Nonce使区块头哈希满足难度要求。简化理解难度越高 → 目标值越小 → 找到合格哈希越难 难度越低 → 目标值越大 → 找到合格哈希越容易2.6 Nonce随机数Nonce是矿工挖矿时反复尝试的数。矿工不断改变 Nonce然后计算区块头哈希直到得到符合 Bits 难度要求的哈希。简化过程如下区块头 Version PrevHash MerkleRoot Timestamp Bits Nonce Hash SHA256(SHA256(区块头)) 如果 Hash 目标难度挖矿成功 否则Nonce 1 后继续尝试2.7 小例子工作量证明如何体现“难”假设要求哈希值必须以 4 个 0 开头0000a34f... 合格 00f19b3c... 不合格 1a04bccc... 不合格矿工并不能直接“设计”一个合格哈希只能不断改变 Nonce 试出来。因此Nonce 可以理解为“试题答案草稿纸上的不断尝试”。3. 区块体 Body 详解区块体主要保存交易数据。不同区块链系统中区块体的组织方式不同但共同点是它承载的是链上真正发生的业务数据。在比特币中区块体主要是交易列表区块体 Body ├── 交易数量 ├── 交易 1 ├── 交易 2 ├── 交易 3 └── ...在以太坊中区块不仅要记录交易还要记录状态变化、收据等信息因此以太坊区块头中会保存多棵树的根哈希例如transaction root交易树根state root状态树根receipt root收据树根。区块体越大完整节点存储和同步压力越大区块头越小轻节点验证越方便。4. 链式结构区块为什么能连成链区块链是一个按照区块生成时间顺序连接形成的分布式数据库。连接的关键就是区块头中的Prev-block Hash字段。4.1 链式结构的形成过程假设有三个区块Block A Hash(A) aaa111 Block B Prev-block Hash aaa111 Hash(B) bbb222 Block C Prev-block Hash bbb222 Hash(C) ccc333最终结构为Block A ← Block B ← Block C aaa111 bbb222 ccc333其中Block B 的区块头记录了 Block A 的哈希Block C 的区块头记录了 Block B 的哈希。4.2 为什么链式结构能防篡改如果攻击者修改 Block A 中的一笔交易交易内容变化Block A 的 Merkle-root 变化Block A 的区块头变化Block A 的 Hash 变化Block B 中保存的 Prev-block Hash 与新 Hash 对不上攻击者必须继续修改 Block B、Block C 以及后续所有区块还要重新完成这些区块的工作量证明。因此越早的区块越难篡改因为后面叠加的区块越多需要重做的计算量越大。4.3 完整副本是什么意思PPT 中提到“形成了区块链表也形成了一个完整的账本”。意思是每个完整节点可以保存从创世区块到当前区块的全部数据节点之间可以互相校验数据是否一致任意节点不需要完全信任单个中心服务器而是通过密码学哈希和共识规则验证账本。5. 哈希列表与二叉树PPT 中对比了 Hash list 和 Binary tree。5.1 Hash List哈希列表Hash List 的基本思想是对每个数据块分别计算哈希然后再把这些哈希组合成一个根哈希。DATA 0 → HASH 0 DATA 1 → HASH 1 DATA 2 → HASH 2 ... DATA n → HASH n HASH 0 HASH 1 ... HASH n → HASH root缺点是如果要证明某个数据在列表中可能需要较多数据辅助验证。5.2 Binary Tree二叉树二叉树是一种每个节点最多有两个子节点的数据结构。Merkle Tree 就是一种典型的哈希二叉树。在 Merkle Tree 中叶子节点通常是交易哈希非叶子节点是左右子节点哈希拼接后再哈希根节点是整棵树的摘要。6. 默克尔树 Merkle TreeMerkle Tree 是区块链中非常重要的数据结构。它的核心目标是用一个根哈希代表大量交易并支持高效的交易存在性证明。6.1 Merkle Tree 的构造过程假设一个区块中包含 4 笔交易Tx1, Tx2, Tx3, Tx4第一步计算每笔交易的哈希。H1 Hash(Tx1) H2 Hash(Tx2) H3 Hash(Tx3) H4 Hash(Tx4)第二步两两组合再哈希。H12 Hash(H1 || H2) H34 Hash(H3 || H4)第三步继续组合到根节点。MerkleRoot Hash(H12 || H34)整体结构MerkleRoot / \ H12 H34 / \ / \ H1 H2 H3 H4 | | | | Tx1 Tx2 Tx3 Tx4其中||表示拼接。6.2 如果交易数量是奇数怎么办如果交易数量是奇数常见做法是复制最后一个哈希使其变成偶数个再继续计算。例如有 5 笔交易H1, H2, H3, H4, H5可以处理为H1, H2, H3, H4, H5, H5然后两两组合。6.3 Coinbase 交易是什么PPT 中提到 Coinbase 交易。它不是交易所 Coinbase而是比特币区块中的特殊交易。Coinbase 交易的作用通常是区块中的第一笔交易用来给矿工发放区块奖励和手续费没有普通交易那样引用前一笔 UTXO也会参与 Merkle Tree 的计算。6.4 Merkle Proof如何证明某笔交易在区块中假设要证明Tx3在区块中。完整节点不需要把所有交易都发给轻节点只需要发送验证路径上的相邻哈希已知Tx3 需要H4、H12、MerkleRoot 验证 H3 Hash(Tx3) H34 Hash(H3 || H4) Root Hash(H12 || H34) 判断 Root 是否等于区块头中的 MerkleRoot如果相等就能证明 Tx3 确实属于该区块。6.5 Merkle Tree 的优势优势解释高效验证不需要下载全部交易只需下载一条验证路径防篡改任意交易变化都会导致 Merkle-root 改变节省空间区块头只保存一个根哈希支持轻节点SPV 可以基于 Merkle Proof 验证交易存在性7. 以太坊中的 MPTMerkle Patricia TreePPT 中介绍了以太坊使用的 MPT即 Merkle Patricia Tree也称默克尔帕特里夏树。7.1 为什么以太坊需要 MPT比特币主要关注交易是否存在、UTXO 是否可花费而以太坊不只是转账系统它还要支持账户余额合约代码合约存储交易执行后的状态变化收据和日志。因此以太坊需要一种能够同时支持哈希校验快速查找状态更新空间压缩轻客户端证明的数据结构。MPT 就是为此设计的。7.2 Trie 树是什么Trie 树又称字典树、前缀树适合存储字符串或键值数据。Trie 树的特点根节点通常不包含字符从根节点到某节点的路径表示一个字符串前缀公共前缀可以共享适合文本检索、自动补全、字典匹配等场景。例如要存储三个词cat car dog可以共享ca前缀root / \ c d | | a o / \ | t r g7.3 Patricia Tree 是什么Patricia Tree 可以看作对 Trie 的压缩。普通 Trie 可能出现很多“只有一个子节点”的节点浪费空间。Patricia Tree 会压缩这些单分支路径。例如普通 Trie root → a → b → c → d Patricia 压缩后 root → abcd这样可以减少节点数量降低存储成本。7.4 Merkle Patricia Trie 的结合MPT 可以理解为三种思想的组合结构提供能力Merkle每个节点有哈希可验证、防篡改Patricia压缩路径节省空间Trie按 key 的路径查找适合键值存储所以 MPT 不是普通树而是具有密码学验证能力的压缩前缀树。7.5 MPT 中的节点类型PPT 中提到为了降低树高、降低操作复杂度MPT 引入了几类节点节点类型作用空节点表示空字符串或不存在的节点扩展节点 Extension Node压缩公共路径分支节点 Branch Node表示路径分叉通常有 16 个分支叶子节点 Leaf Node保存最终的 key-value 数据7.6 MPT 中 key 和 value 是什么在以太坊状态树中key 账户地址经过编码后的路径 value 账户状态信息账户状态可能包括nonce账户交易次数balance账户余额storageRoot合约存储树根codeHash合约代码哈希。在交易树中key 交易在区块中的序号 value 交易内容在收据树中key 交易在区块中的序号 value 交易执行后的收据信息7.7 以太坊区块中的三棵树PPT 中提到以太坊区块中包含交易、收据和状态三类树树区块头中的根主要用途交易 MPTtransaction root证明某笔交易是否在该区块中收据 MPTreceipt root证明交易执行结果、日志、事件是否存在状态 MPTstate root证明某个账户余额、合约状态等全局状态7.8 为什么说状态 MPT 会不断更新以太坊是账户模型。每笔交易执行后都可能改变账户余额、合约状态或 nonce。例如Alice 向 Bob 转账 1 ETH执行后Alice 余额减少 Bob 余额增加 Alice nonce 增加 状态树更新 state root 改变这就是为什么每个以太坊区块头都要记录新的state root。7.9 MPT 能支持哪些查询PPT 中列出了轻客户端可以实现的查询。整理如下查询问题由哪棵树处理这笔交易是否包含在某个区块中交易 MPT某地址过去 30 天内发出某类事件的所有实例收据 MPT某账户当前余额是多少状态 MPT某账户是否存在状态 MPT某合约交易的输出是什么状态 MPT 收据 MPT8. SPV简化支付验证SPV 的英文全称是 Simplified Payment Verification中文通常称为“简化支付验证”。8.1 SPV 解决什么问题完整节点需要保存完整区块数据数据量很大。对于手机钱包、物联网设备等资源有限的终端来说保存完整区块链不现实。SPV 的目标是不下载完整区块体只保存区块头也能验证某笔交易是否已经被区块链网络确认。8.2 SPV 验证的是“支付”不是完整交易合法性PPT 中特别强调SPV 技术的设计目标是验证“支付”而不是验证“交易”。这句话非常重要。交易验证需要检查签名、余额是否足够、是否双花、脚本是否合法等支付验证只验证某笔交易是否已经出现在某个区块中并且后面有足够确认数。换句话说SPV 用户不能像完整节点一样独立验证所有共识规则它主要依赖区块头链Merkle Proof网络中多数算力选择的最长有效链。8.3 SPV 的验证思路SPV 节点验证交易的大致流程SPV 钱包只同步区块头当用户关心某笔交易时向完整节点请求相关证明完整节点返回包含该交易的区块头该交易的 Merkle Proof该区块之后的区块头链SPV 节点利用 Merkle Proof 验证交易属于该区块再检查该区块后面有多少确认数确认数足够时认为支付可信。8.4 举例如何判断一笔交易有 6 个确认假设交易Tx100被打包进区块高度 1000。当前最长链高度为 10061000 → 1001 → 1002 → 1003 → 1004 → 1005 → 1006那么Tx100所在区块后面已经追加了 6 个区块通常可以说它有 6 个确认。注意不同系统、不同金额、不同风险场景对确认数要求不同。9. 布隆过滤器 Bloom Filter布隆过滤器是一种空间效率很高的概率型数据结构。它可以用来判断一个元素是否可能属于某集合。9.1 布隆过滤器能回答什么问题布隆过滤器回答的问题是某元素是否在集合中但它的回答有两个特点回答含义一定不在结果可靠可能在可能是真的也可能是假阳性PPT 中强调布隆过滤器不能完全确定一定在一个集合内 而不能完全确定一定在一个集合内。更准确地说布隆过滤器可以准确判断“不存在”但不能百分百确认“存在”。9.2 布隆过滤器的基本原理布隆过滤器由一个位数组和多个哈希函数组成。假设位数组初始全为 0位置0 1 2 3 4 5 6 7 8 9 值 0 0 0 0 0 0 0 0 0 0插入元素X时用多个哈希函数计算位置H1(X) 2 H2(X) 5 H3(X) 7把对应位置置为 1位置0 1 2 3 4 5 6 7 8 9 值 0 0 1 0 0 1 0 1 0 0查询元素Y时如果它对应的某个位置为 0就说明它一定不在集合中。如果所有位置都是 1只能说明它“可能在集合中”。9.3 为什么会出现误判因为不同元素可能通过哈希函数映射到相同位置。例如X 设置了位置 2、5、7 Z 设置了位置 1、5、8查询 Y 时假设 Y 对应位置刚好是2、5、8虽然 Y 没有插入过但这些位置已经被其他元素置为 1于是布隆过滤器会说Y 可能在集合中这就是假阳性。9.4 布隆过滤器在 SPV 中的作用SPV 钱包如果直接向网络询问请告诉我和地址 A 有关的所有交易就会暴露隐私因为对方知道这个钱包关心地址 A。布隆过滤器可以让 SPV 节点发送一个“模糊条件”请把可能和我有关的交易发给我完整节点根据 Bloom Filter 过滤区块中的交易把可能相关的数据返回给 SPV 节点。这样可以减少无关数据下载提高查询效率一定程度保护隐私但不能完全保护隐私因为过滤模式仍可能被分析。9.5 例题查找过去 10 天与某智能合约相关的交易PPT 中的问题是要查找过去 10 天发生的所有和这个智能合约相关的交易怎么找可以分场景回答。情况一完整节点完整节点保存完整区块和状态可以直接遍历过去 10 天内的区块1. 找到过去 10 天对应的区块高度范围 2. 遍历这些区块中的交易 3. 筛选 to/from 地址等于目标合约地址的交易 4. 如果需要事件日志再读取交易收据 logs 5. 汇总结果情况二轻节点 / SPV 思路轻节点不保存完整交易数据可以1. 保存或同步区块头 2. 向完整节点请求与合约地址相关的交易/收据证明 3. 使用 Merkle Proof 或 MPT Proof 验证返回结果 4. 根据区块高度或时间戳限定过去 10 天情况三以太坊场景以太坊中不仅要找交易还可能要找合约事件。交易是否存在交易 MPT 交易执行结果和事件日志收据 MPT 合约当前状态状态 MPT如果只是找“调用该合约的交易”主要看交易中的to字段如果要找“合约发出的事件”则主要看 receipt logs。10. 综合例题与答疑10.1 例题一为什么修改一笔交易会影响区块哈希**问题**某区块中一笔交易被篡改为什么区块哈希会变化答案交易变化 → 交易哈希变化 → Merkle Tree 中相关父节点哈希变化 → Merkle-root 变化 → 区块头变化 → 区块哈希变化因为区块头中保存了 Merkle-root所以区块体中的交易变化最终会传导到区块头哈希。10.2 例题二区块头为什么不直接保存所有交易因为交易数量可能很多直接把交易全部塞进区块头会导致区块头巨大不利于传播和轻节点验证。使用 Merkle-root 后区块头只需保存一个 32 字节左右的根哈希就能代表整个交易集合。10.3 例题三SPV 能不能发现双花SPV 不能像完整节点一样独立检查所有双花情况。它主要通过交易是否被打包进区块区块是否属于最长链后续确认数是否足够来降低双花风险。因此SPV 是一种轻量级验证方案安全性依赖网络中诚实算力和完整节点返回的证明。10.4 例题四Merkle Tree 和 MPT 有什么区别对比项Merkle TreeMPT主要应用比特币交易集合证明以太坊账户、交易、收据证明结构哈希二叉树压缩前缀树 Merkle 哈希查询方式根据交易哈希验证存在性根据 key 路径查找 value是否适合频繁状态更新一般更适合典型根哈希Merkle-rootstate root / tx root / receipt root10.5 例题五布隆过滤器为什么不能删除元素普通布隆过滤器中一个位置可能被多个元素共同设置为 1。如果删除某个元素时把对应位置改回 0可能会误删其他元素的标记导致原本存在的元素被判断为不存在。因此普通 Bloom Filter 不支持安全删除。若要支持删除需要使用 Counting Bloom Filter 等变体。11. 复习速记表11.1 区块结构速记概念速记区块区块头 区块体区块头连接区块、验证区块、支持共识区块体保存交易数据Prev-block Hash指向前一区块形成链Merkle-root本区块所有交易的总摘要Nonce挖矿时不断尝试的随机数Bits难度目标压缩表示11.2 树结构速记数据结构关键词主要用途Hash List顺序哈希简单数据摘要Binary Tree左右子树Merkle Tree 基础结构Merkle Tree根哈希、验证路径交易存在性证明Trie前缀共享字符串/键值检索Patricia Tree路径压缩节省空间MPTMerkle Patricia Trie以太坊状态、交易、收据证明Bloom Filter一定不在、可能在高效集合过滤11.3 高频问答Q1区块链为什么难以篡改因为每个区块都包含前一区块哈希且交易数据通过 Merkle-root 写入区块头。修改历史交易会导致 Merkle-root 和区块哈希变化还会破坏后续区块的链接攻击者必须重算后续所有区块的工作量证明。Q2Merkle-root 的核心意义是什么用一个根哈希代表整个交易集合并支持高效验证某笔交易是否属于该区块。Q3SPV 节点保存什么主要保存区块头不保存完整区块体。需要验证某笔交易时再向完整节点请求 Merkle Proof。Q4Bloom Filter 的判断结果怎么理解返回“不在”一定不在返回“可能在”可能在也可能是误判。Q5以太坊为什么要用 MPT因为以太坊不仅要记录交易还要维护账户状态、合约状态、交易收据等复杂键值数据。MPT 同时具备快速查找、路径压缩和哈希证明能力。12. 一页总结区块链的区块结构可以概括为区块 区块头 区块体 区块头 Version PrevHash MerkleRoot Timestamp Bits Nonce 区块体 交易列表 / 状态变化相关数据区块通过Prev-block Hash首尾相连形成不可轻易篡改的链式账本交易通过 Merkle Tree 形成 Merkle-root写入区块头实现交易集合的高效摘要和存在性证明轻节点通过 SPV 只保存区块头并借助 Merkle Proof 验证支付是否存在以太坊进一步使用 MPT 管理交易、收据和账户状态使复杂的智能合约系统也能实现可验证的数据查询Bloom Filter 则用于高效过滤可能相关的数据降低轻节点的数据下载压力。最终理解区块结构的本质不是简单“存数据”而是通过哈希、树结构和链式引用把数据组织成一个可验证、可追溯、难篡改、可分布式维护的账本系统。