本文档解释了在 go-ethereum (Geth) 实现中,以太坊的世界状态是如何被维护、修改和存储的。状态管理是跟踪以太坊区块链中的账户余额、合约代码和存储数据的一个关键组件。
有关交易执行期间状态变化的信息,请参阅 交易处理。有关智能合约执行的具体细节,请参阅 以太坊虚拟机。
以太坊的世界状态是地址(账户)和账户状态之间的映射。它代表了区块链上所有账户的当前状态,并被维护为一个 Merkle Patricia Trie 结构,以确保数据的完整性和高效验证。
以太坊有两种类型的账户:
状态 Trie 将账户地址映射到账户对象,账户对象包括:
来源:core/state/statedb.go68-79 core/types/transaction.go54-63
核心状态管理依赖于几个关键数据结构:
来源:core/state/statedb.go79-158 core/state/state_object.go42-86 trie/trie.go38-60
StateDB (core/state/statedb.go) 是与以太坊状态交互的主要接口。它提供了以下方法:
StateDB 提供了访问和修改账户的方法,维护内存状态对象的缓存,并协调 Trie 操作。
来源:core/state/statedb.go161-188 core/state/statedb.go294-325 core/state/statedb.go407-434
新的 StateDB 在每个区块处理开始时创建,通常使用前一个区块的状态根。在交易执行期间,StateDB 用于读取和修改状态。
来源:core/state/statedb.go160-188 core/state/statedb.go294-305 core/state/statedb.go407-455
stateObject 结构体表示在状态转换期间被修改的以太坊账户。它包含:
stateObject 处理数据缓存和账户状态的分层更新。
dirtyStorage:当前交易中进行的更改。pendingStorage:当前区块中进行的更改,但已按交易最终确定。uncommittedStorage:自上次提交以来的所有更改。originStorage:来自数据库的原始值。来源:core/state/state_object.go42-86 core/state/state_object.go89-110
getOrNewStateObject 访问账户时创建。finalise)。commit)。在此过程中,状态对象会跟踪原始值、待定更改,并确保所有修改都可以通过状态根进行验证。
来源:core/state/statedb.go610-627 core/state/state_object.go274-287
以太坊智能合约将数据存储在键值存储中,称为存储。每个合约都有自己的存储 Trie,其根存储在账户对象中。
合约存储操作通过以下几种方法进行管理:
GetState/SetState:读取和写入存储值。GetCommittedState:获取存储值,不考虑未提交的更改。updateTrie/updateRoot:将待定更改刷新到存储 Trie。来源:core/state/state_object.go170-208 core/state/state_object.go210-234 core/state/state_object.go282-316
Journal(core/state/journal.go)记录交易执行期间的所有状态更改,以便能够恢复到之前的状态。这对于处理交易失败、Gas 不足以及创建快照至关重要。
日志系统支持:
Snapshot() 创建恢复点。RevertToSnapshot() 回滚更改。来源:core/state/statedb.go711-718 core/state/journal.go
当交易执行时,它们通过 StateDB 修改状态。该过程遵循几个阶段:
Finalise() 以便为下一笔交易做准备。IntermediateRoot() 生成 Trie 根哈希。Commit() 创建最终状态。Finalise 方法负责处理交易后的清理工作:
来源: core/state/statedb.go728-766 core/state/statedb.go771-917
当一个区块被确定时,所有状态更改必须被提交到持久存储。这分几个步骤完成:
Commit 方法将所有状态对象最终确定提交过程确保所有状态更改都被持久存储,并且可以通过新的状态根哈希进行引用。
来源: core/state/state_object.go418-452 core/state/statedb.go771-917 trie/trie.go
Go-ethereum 实现了多种状态管理的优化技术
Trie 预取器(StateDB 中的 prefetcher)通过以下方式优化 Trie 节点检索:
来源: core/state/statedb.go190-223 core/state/statedb.go771-907
状态数据最终存储在分层数据库结构中
这种架构提供了:
来源: core/state/database.go trie/trie.go ethdb/database.go core/rawdb/database.go
Geth 中的状态管理通过一套复杂的 Trie、缓存和日志系统来维护以太坊的世界状态。这种架构平衡了几个关键要求:
StateDB 提供了该复杂系统的干净接口,抽象了底层的 Trie 操作和数据库交互,同时提供了对当前状态的一致视图。
来源: core/state/statedb.go core/state/state_object.go trie/trie.go