以太坊最初怎么存储,从Merkle Patricia树到状态根
以太坊作为区块链2.0的代表性项目,其核心设计之一是通过“状态存储”实现去中心化的账户管理,与比特币仅记录UTXO(未花费交易输出)不同,以太坊需要维护全球账户状态(包括账户余额、合约代码、存储数据等),这一机制的最初实现奠定了其智能合约运行的基础,本文将追溯以太坊最初(2015年 Frontier 主网上线时)的存储架构,解析其核心组件与设计逻辑。

以太坊存储的底层载体:Merkle Patricia树
以太坊最初存储的核心是Merkle Patricia树(简称MPT),一种结合了Merkle树和Patricia Trie(前缀树)的数据结构,它通过递归哈希映射,将全局状态、交易数据、收据等全部存储在以太坊的“世界状态”(World State)中,实现了高效验证与数据完整性。
世界状态:全局账户的“总账本”
以太坊的“世界状态”是一个MPT,其每个叶子节点存储一个账户对象(Account Object),账户对象包含四个核心字段:
nonce:账户发起的交易数量(防止重放攻击);balance:账户的以太币余额(单位:wei);storageRoot:该账户关联的合约存储树的根哈希(仅合约账户有);codeHash:账户合约代码的哈希(仅合约账户有,普通账户为空哈希)。
所有账户通过地址(address)作为键,在MPT中组织成有序结构,当用户向地址0x123…转账时,以太坊会更新该账户的balance,并重新计算世界状态的根哈希(称为“状态根”),这个根哈希被打包在每个区块的头部,成为区块不可篡改的核心证据之一。
合约存储树:状态数据的“分层管理”
对于智能合约账户,其状态数据(如变量值、数组等)存储在一个独立的MPT中,称为“合约存储树”(Storage Trie),这个树的根哈希就是账户对象中的storageRoot。

一个简单的合约存储变量uint256 x = 42,其存储过程为:
- 将变量
x的“键”(通常基于Solidity编译后的内存偏移量,如0x0)和“值”(42的编码)作为叶子节点,插入到合约存储树中; - 计算存储树的根哈希,更新到账户对象的
storageRoot字段; - 当合约状态变更时(如
x = 100),仅更新合约存储树中对应的叶子节点,并重新计算根哈希,最终影响世界状态的根哈希。
这种分层设计实现了“全局状态-账户状态-合约存储”的解耦,使得状态更新仅涉及必要的树节点,而非全量数据,大幅提升了效率。
数据持久化:从内存到区块链
以太坊最初的状态存储并非完全“链上”存储,而是结合了内存、数据库与链上索引的混合模式。
内存中的缓存:加速状态访问
为了提升性能,以太坊节点(如Geth客户端)会维护一个内存中的状态缓存(State Cache),当读取账户状态时,优先从缓存中查找;若缓存未命中,再从持久化存储(如LevelDB)中加载并写入缓存,状态更新(如转账、合约调用)也先在缓存中进行,待区块确认后再批量写入持久化存储,减少磁盘IO压力。

持久化存储:LevelDB的底层支撑
以太坊最初使用LevelDB作为默认的持久化存储引擎,用于保存完整的MPT数据,LevelDB是一个键值数据库,其键为MPT节点的哈希(或路径),值为节点的序列化数据(包括节点类型、子节点引用、键值对等)。
世界状态MPT的根哈希0xabc…对应一个序列化的内部节点,该节点包含子节点的哈希引用,通过递归查询LevelDB,最终可还原整棵MPT的结构,这种设计使得节点无需存储全量数据,仅通过哈希索引即可定位任意状态,节省了存储空间。
链上存储:状态根的“轻量化”验证
虽然完整的状态数据存储在节点的LevelDB中,但以太坊通过“状态根”实现了链上轻量化验证,每个区块头包含三个关键哈希:
stateRoot:世界状态的MPT根哈希;transactionsRoot:交易列表的MPT根哈希;receiptsRoot:交易收据的MPT根哈希。
节点无需下载所有状态数据,仅通过验证区块头中的stateRoot,即可确认状态变更的合法性,当用户声称账户A的余额为X时,只需提供从stateRoot到该账户状态路径的Merkle证明,节点即可快速验证其真伪,无需访问完整的状态数据库。
最初存储设计的优势与局限
优势
- 数据完整性:MPT的递归哈希机制确保任何状态变更都会导致根哈希变化,恶意篡改数据会立即被验证失败;
- 高效查询:Patricia Trie的前缀压缩特性减少了存储空间,同时支持快速的前缀匹配查询(如合约变量查找);
- 可扩展性:分层存储(世界状态-账户-合约存储)使得状态更新仅影响局部节点,适合大规模状态管理。
局限
- 存储成本高:随着账户数量和合约状态增长,LevelDB中的MPT节点数据膨胀,节点存储压力增大;
- 状态同步慢:新节点加入时需下载完整的状态数据(截至最新区块的
stateRoot对应的全部MPT节点),导致“状态同步”成为早期以太坊节点的痛点; - 中间状态缺失:最初的设计仅保存“最新状态”,历史中间状态未被完整记录,难以追溯状态变更的完整路径。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。




