以太坊,作为全球领先的智能合约平台,其核心功能之一是存储和管理链上数据,理解以太坊如何组织和存储数据,对于开发者、节点运营者乃至任何希望深入了解其底层机制的人都至关重要,以太坊的存储数据格式并非简单的键值对堆砌,而是一套精心设计、高效且安全的体系,其核心是Merkle Patricia Trie (MPT,默克尔帕特里夏树),本文将详细探讨以太坊的存储数据格式,包括其核心组件MPT、账户模型以及具体的数据存储结构。
核心基石:Merkle Patricia Trie (MPT)
MPT是以太坊状态存储、交易和收据存储的底层数据结构,它是一种结合了Merkle Tree(默克尔树)和Patricia Trie(帕特里夏树,也称为基数树 Radix Tree)优化的数据结构。
-
Patricia Trie (基数树):
- Patricia Trie是一种压缩前缀树,它通过共享公共前缀来高效存储键值对,特别适合存储像以太坊地址这样的十六进制字符串。
- 与普通前缀树相比,Patricia Trie能显著减少树的深度和节点数量,从而提高查询效率并节省存储空间,它将键值对存储在树的叶子节点中,内部节点则用于指导查找路径。
-
Merkle Tree (默克尔树):
- Merkle Tree是一种哈希树,其特点是每个非叶子节点的值都是其所有子节点值的哈希组合。
- 这种结构带来了一个关键特性:完整性验证,通过计算根节点的哈希值(Merkle Root),可以高效地验证任意数据块是否被篡改,如果树中任何一个叶子节点的数据发生变化,都会引起其所有父节点哈希值的连锁改变,最终导致根哈希值的改变。
-
Merkle Patricia Trie (MPT)的结合优势:
- MPT将Patricia Trie的高效查询和存储特性与Merkle Tree的完整性验证能力相结合。
- 在以太坊中,每个区块头都包含一个状态根(State Root)、一个交易根(Transactions Root)和一个收据根(Receipts Root),这些根就是对应MPT的根哈希值。
- 状态根:代表整个以太坊网络在某个区块高度的所有账户状态的MPT根哈希。
- 交易根:代表该区块中所有交易的MPT根哈希。
- 收据根:代表该区块中所有交易执行后产生的收据的MPT根哈希。
- 这种设计使得轻客户端(如手机钱包)能够高效地验证交易是否被包含在某个区块中,以及状态是否发生了变化,而无需下载整个区块链数据。
账户模型与状态存储
以太坊采用的是账户模型(Account-based Model),与比特币的UTXO模型不同,每个账户都有一个唯一的地址,状态数据就是所有账户信息的集合。
-
账户类型:
- 外部账户 (Externally Owned Account, EOA):由用户私钥控制的账户,用于发起交易、持有以太坊等,没有关联代码。
- 合约账户 (Contract Account):由代码控制,当收到特定交易时,其代码会被执行,有关联的代码和存储。
-
账户状态数据结构: 每个账户(无论是EOA还是合约账户)在状态树中都由以下字段表示:
- nonce:
- 对于EOA:该账户发起的交易数量。
- 对于合约账户:该账户创建的合约数量。
- balance:账户持有的以太币余额,以wei(1 ETH = 10^18 wei)为单位。
- storageRoot:仅合约账户有,指向该合约账户的存储树(Storage Trie)的根哈希,存储树用于存储合约的持久化变量数据,它也是一个MPT,EOA的storageRoot为空。
- codeHash:仅合约账户有,指向该合约账户代码的哈希值,EOA的codeHash是空字符串的哈希,合约代码本身存储在一个单独的

- nonce: