关注

状态树:区块链如何记录当前世界状态

在这里插入图片描述

状态树是区块链系统中用来表示“当前账本状态”的核心数据结构。它不是记录过去发生了哪些交易,而是记录交易执行之后,系统现在变成了什么样。

在比特币里,账本主要围绕 UTXO 运行;在以太坊里,账本则更像一个全球共享的状态机。每个区块都会让系统从一个状态转移到另一个状态。

上一个状态 + 本区块交易 = 新状态

状态树的作用,就是把这个“新状态”用一种可验证、可追踪、可证明的方式组织起来。


一、什么是状态?

在区块链语境里,“状态”指的是某个时刻系统里的当前结果。

例如在以太坊中,状态包括:

状态类型示例
账户余额Alice 有 3 ETH
账户 nonceAlice 已经发起过 7 笔交易
合约代码某个地址部署了一段智能合约代码
合约存储某个合约变量 x 的值为 100
代币余额ERC20 合约记录 Bob 有 200 个代币

这些不是单笔交易,而是交易执行后的结果。

比如 Alice 向 Bob 转账 1 ETH:

转账前:Alice 3 ETH,Bob 5 ETH
转账后:Alice 2 ETH,Bob 6 ETH

状态树关心的是转账后的当前状态。


二、为什么需要状态树?

如果系统里只有几个账户,直接用表格记录余额就可以。但区块链是全球共享账本,可能包含海量账户、合约和存储项。

节点需要解决几个问题:

  1. 如何高效查找某个账户的当前状态?
  2. 如何证明某个账户状态确实属于当前账本?
  3. 如何发现状态被篡改?
  4. 如何让区块头用一个很小的字段承诺整个系统状态?
  5. 如何支持轻客户端验证某个账户或合约变量?

状态树就是为了解决这些问题而设计的。


三、状态树的基本结构

简化来看,状态树把所有账户组织成一棵树,树根是一个哈希值,称为 状态根 State Root

状态根 State Root

Alice 账户

Bob 账户

合约账户

余额 3 ETH

Nonce 7

余额 5 ETH

Nonce 2

余额 10 ETH

代码哈希

存储根 Storage Root

真实以太坊使用的不是普通二叉树,而是一种叫 Merkle Patricia Trie 的结构,中文常译为 默克尔帕特里夏树默克尔前缀树

它结合了两类思想:

结构作用
Merkle Tree通过哈希保证数据不可篡改,并支持证明
Patricia Trie通过键路径组织数据,便于查找和压缩

四、状态根:用一个哈希承诺整个世界状态

状态树最重要的产物是状态根。

所有账户和合约状态

组织成状态树

逐层计算哈希

得到状态根

写入区块头

状态根的意义是:

用一个很短的哈希值,代表整个区块执行完成后的全局状态。

如果任何账户余额、nonce、合约代码哈希或合约存储发生变化,相关节点哈希会变化,最终状态根也会变化。

Alice 余额变化

Alice 账户节点哈希变化

父节点哈希变化

更高层节点哈希变化

状态根变化

这使得区块链可以做到:

小小一个 stateRoot,承诺整个世界状态。

五、状态树在区块中的位置

以太坊每个区块头中都会包含状态根。可以把它理解为:

这个区块里所有交易执行完以后,系统状态的最终摘要。

简化流程如下:

上一区块状态根

执行本区块交易

更新账户和合约状态

计算新状态根

写入新区块头

当一个节点收到新区块时,它会:

  1. 从上一区块的状态开始;
  2. 按顺序执行新区块中的交易;
  3. 更新账户余额、nonce 和合约存储;
  4. 重新计算状态根;
  5. 检查计算结果是否等于区块头里的状态根。

如果不一致,区块就是无效的。


六、账户状态里有什么?

以太坊账户大致分为两类:

账户类型说明
外部账户 EOA由私钥控制的普通账户
合约账户由智能合约代码控制的账户

每个账户状态通常包含四类核心信息:

字段含义
nonce外部账户发起交易次数,或合约创建计数
balanceETH 余额
storageRoot合约存储树根
codeHash合约代码哈希

账户状态

Nonce

Balance

Storage Root

Code Hash

外部账户没有合约代码,合约账户则会通过 codeHash 指向合约代码,并通过 storageRoot 指向自己的存储树。


七、存储树:合约自己的小账本

状态树记录所有账户;但每个智能合约还有自己的内部存储。

例如一个 ERC20 代币合约可能记录:

Alice 有 200 个代币
Bob 有 500 个代币
总供应量为 1000000

这些变量不会直接平铺在全局状态树里,而是放在该合约账户自己的 存储树 Storage Trie 中。

全局状态树

某个合约账户

ETH 余额

代码哈希

存储根

变量 totalSupply

映射 balances Alice

映射 balances Bob

因此,以太坊状态可以理解为两层结构:

全局状态树:管理所有账户
合约存储树:管理单个合约内部变量

八、状态树和交易树、收据树的区别

以太坊中常见的树不止状态树。

记录什么根哈希写在哪里
状态树 State Trie区块执行后的账户和合约状态区块头 stateRoot
交易树 Transaction Trie本区块包含的交易区块头 transactionsRoot
收据树 Receipt Trie交易执行结果、日志、gas 使用等区块头 receiptsRoot

区块头

状态根 State Root

交易根 Transactions Root

收据根 Receipts Root

执行后的世界状态

本区块交易列表

交易执行收据和日志

三者的区别可以简单概括:

交易树记录发生了什么;
收据树记录执行结果如何;
状态树记录世界变成了什么。

九、状态树如何支持轻客户端证明?

状态树的 Merkle 属性让它可以提供状态证明。

假设轻客户端想知道:

Alice 在某个区块高度的 ETH 余额是不是 3 ETH?

它不必下载完整状态树,只需要获得:

  1. 区块头中的 stateRoot;
  2. Alice 账户数据;
  3. 从 Alice 账户节点到 stateRoot 的证明路径。

Alice 账户数据

证明节点 1

证明节点 2

状态根

区块头中的 stateRoot

轻客户端可以沿着证明路径重新计算哈希。如果最终得到的根等于区块头里的 stateRoot,就可以确认:

Alice 的账户状态确实被这个区块的状态根所承诺。

这类证明常被称为 Merkle Proof状态证明


十、状态树和比特币 UTXO 模型的区别

状态树常见于账户模型区块链,而比特币采用 UTXO 模型。

对比项比特币以太坊
账本模型UTXO 模型账户模型
当前状态未花费交易输出集合账户和合约状态
余额来源汇总可用 UTXO直接读取账户余额
主要树结构区块内交易 Merkle 树状态树、交易树、收据树
合约存储非主要设计目标通过存储树管理

比特币更像现金零钱:

你有哪些还没有花掉的纸币?

以太坊更像账户系统:

每个账户现在有多少钱?每个合约变量现在是多少?

十一、状态树的优点

状态树带来几个重要优势:

优点说明
可验证任意状态变化都会影响状态根
可证明可以证明某个账户或变量属于某个状态根
可同步节点可以围绕状态根检查一致性
可追踪每个区块都有执行后的状态承诺
适合智能合约能表达复杂合约存储

状态树使区块链不仅能记录“转账历史”,还能记录复杂应用的当前状态。


十二、状态树的成本和挑战

状态树也不是没有代价。

挑战说明
存储压力大量账户和合约状态会持续膨胀
访问成本合约频繁读写状态会增加节点负担
状态膨胀无用或长期不用的数据仍可能占用状态
实现复杂Merkle Patricia Trie 比普通树复杂
同步复杂新节点同步和验证状态需要额外机制

这也是为什么以太坊生态长期关注状态租金、状态过期、Verkle Tree、无状态客户端等方向。


十三、一个完整例子:转账如何改变状态树

假设 Alice 向 Bob 转账 1 ETH。

初始状态:

账户余额nonce
Alice3 ETH7
Bob5 ETH2

交易执行后:

账户余额nonce
Alice2 ETH8
Bob6 ETH2

状态树中的变化路径如下:

Alice 向 Bob 转账 1 ETH

Alice 余额减少

Alice nonce 增加

Bob 余额增加

Alice 账户节点哈希变化

Bob 账户节点哈希变化

上层路径哈希变化

新的状态根

新区块头会保存这个新的状态根。其他节点只要重新执行交易,也应该得到同一个状态根。


十四、总结

状态树是账户模型区块链中的核心结构。它的本质是:

用一棵带哈希的树组织全局账户和合约状态,并用状态根代表整个系统当前状态。

它解决了三个关键问题:

  1. 表示问题:如何表示当前全局状态;
  2. 验证问题:如何发现状态是否被篡改;
  3. 证明问题:如何向轻客户端证明某个账户或变量的值。

一句话概括:

交易树说明区块里发生了什么,收据树说明执行结果如何,状态树说明世界现在变成了什么。

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2401_88644935/article/details/161508449

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--