以太坊状态根和交易根,分别证明什么?

 / 
1

状态根证明的是执行完这个区块里所有交易之后,整个以太坊世界的账户状态变成了什么样;交易根证明的是这个区块里到底打包了哪些交易、顺序如何。两者都是区块头里的 32 字节哈希,但承诺的对象完全不同:一个指向"结果",一个指向"输入"。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

状态根:给"执行后的世界"拍一张快照

以太坊本质上是一台状态机。每个账户的余额、nonce、合约代码和合约存储,共同构成了"世界状态"。状态根就是这个世界状态在一棵默克尔帕特里夏树(MPT)上的根哈希。

关键在于时点。以太坊执行规范对 state_root 的定义是:执行完这个区块内所有交易之后,状态树的根哈希。也就是说,状态根承诺的是"这些交易做完之后,全网账户变成了什么样"。如果你的账户余额因为区块里的某笔交易发生了变化,这个变化会反映在状态根所代表的那棵树的对应叶子里。

状态根有一个容易被误解的地方:它描述的是累计状态,不是本区块的增量。同一个状态根可能在连续多个区块里重复出现(如果这几个区块没有改变任何账户状态)。它也不告诉你状态是怎么变成这样的,只告诉你"现在是这样"。

交易根:给"这个区块装了哪些交易"列一份清单

交易根指向另一棵 MPT,这棵树的叶子是本区块包含的交易,键是交易在区块内的序号,值是交易本身的编码。

它回答的问题很直接:这个区块里到底有哪些交易,按什么顺序排列。如果你想证明某笔交易确实被打包进了某个区块,不需要下载整个区块的所有交易,只需要沿着交易树从根到对应叶子的默克尔路径,提供路径上的兄弟哈希,就能验证。验证成本与区块大小成对数关系,不随链的长度增长。

交易根承诺的是"输入",不是"结果"。它不关心这些交易执行后账户变成了什么样,那是状态根和收据根的事。

一个区块头里其实有三棵树,别把收据根漏掉

除了状态根和交易根,以太坊区块头里还有第三个根:收据根(receipts_root)。它指向一棵由交易收据构成的树,收据记录了每笔交易执行后的结果——成功还是失败、消耗了多少 Gas、产生了哪些日志。

承诺什么回答的问题
交易根本区块打包的交易列表"这个块里有什么交易?"
收据根每笔交易执行后的收据"每笔交易执行结果如何?"
状态根执行完所有交易后的全局状态"做完这些之后,世界变成了什么样?"

交易根和收据根都是每块独立的,只描述当前区块;状态根则是跨区块持续的,它承载的是从创世区块一路累积到现在的全局状态。

为什么区分这两个根对你有用

如果你在区块浏览器上查一笔交易,看到它被打包进了某个区块,你其实在依赖交易根来确认"它确实在这个块里"。交易根让你可以验证交易被包含,而不需要信任浏览器告诉你的结果。

但交易被打包不等于它执行成功了。一笔失败的交易同样会被打包,同样计入交易根。要知道它执行后到底发生了什么——转账是否到账、合约调用是否生效——你需要看收据根对应的收据,以及最终状态根里你的账户余额有没有变。交易根证明"它被处理了",状态根证明"处理完之后你的余额对了"。两者缺一不可,但各自只回答自己那一半问题。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

参考资料

  1. Ethereum Execution Specs·blocks.py(state_root 与 transactions_root 定义),日期:2026-11-05
  2. Ethereum Yellow Paper·The Block(stateRoot、transactionsRoot、receiptsRoot 定义),日期:2026-11-05
  3. Ethereum Foundation Blog·State Tree Pruning,日期:2026-11-05
  4. Bitroot·世界状态与 Merkle Patricia Trie:stateRoot 如何承诺一切,日期:2026-11-05