在ETH的存储结构中,使用了MerklePatriciaTrie(MPT),这种结构为何具有“可验证性”和“前缀压缩”特性?今天就来较详细的了解下。MerklePatriciaTrie=PatriciaTrie+MerkleTree的结合体。以太坊用来存储账户状态、存储数据
在ETH的存储结构中,使用了 Merkle Patricia Trie(MPT),这种结构为何具有“可验证性”和“前缀压缩”特性?今天就来较详细的了解下。
Merkle Patricia Trie = Patricia Trie + Merkle Tree 的结合体。以太坊用来存储账户状态、存储数据和交易数据的核心数据结构。
在开始前,先来重温下Merkle Tree 和 Patricia Trie
Trie(发音类似“try”)其实就是一种为了节省空间的数据结构,用来存储多个有共同前缀的 key。
假如有三个键:
appleappappricotTrie 会这样存储它们👇:
(a)
|
p
|
p
/ \
l r
| |
e i
|
c
|
o
|
t
你会发现:
app 是所有键的公共前缀 → 只存一遍!节省空间,又便于查找
Merkle Tree 是一种“能验证数据没被篡改”的树结构。
假设有 4 个交易:
tx1, tx2, tx3, tx4
Merkle Tree 计算方式:
h1 = hash(tx1) ……h12 = hash(h1 + h2) …… root
/ \
h12 h34
/ \ / \
h1 h2 h3 h4
要验证tx1是否改动过,只要给 tx1、h2、h34,就能“复原路径”,算出 root,从而得到验证。
→ 就像“发票 + 验证公式”,可验证、难伪造
MPT 使用了 哈希链结构,可以生成从根节点(Root)到任意叶子节点(Leaf)的路径,每个节点都是通过 哈希加密后的内容指针(Hash pointer) 引用子节点。
每个节点的哈希值由其子节点内容计算而来;
根节点的哈希就是整个状态的唯一表示 —— 即区块头中的 stateRoot;
给定某个 key,要证明其值是某个值,只需要:
✅ 结果:
路径 + 根哈希,轻节点也能验证数据的合法性;Merkle Proof 可用于轻客户端、ZK Rollup 等场景中普通的 Trie(字典树)为每个字符创建一个节点,比如:
插入 key1: "dog"
插入 key2: "dove"
普通 Trie: d → o → g 和 d → o → v → e 分支
Patricia Trie 采用了路径压缩,合并了唯一路径上的所有节点成一条路径:
(d)
|
o
/ \
g v
|
e
在以太坊中:
所有键都转换为十六进制编码,比如地址变为 40 位二进制数;
若多个键有相同前缀,会被压缩成一个 node;
节点分为:
✅ 结果:
以太坊的状态存储结构包括三个主要 MPT:
| Trie 类型 | 存储内容 | 根哈希位置 |
|---|---|---|
| 状态树 | 每个地址的账户信息 | stateRoot |
| 存储树 | 合约存储变量 key→val | 合约 storageRoot |
| 交易树 | 区块内所有交易 | transactionsRoot |
例如,验证账户地址 0xabc...123 在某个区块中,其余额是 1 ETH,是否真实可信,不是伪造数据
stateRootstateRoot 是整棵账户状态树的根哈希。block = await provider.getBlock(blockNumber);
stateRoot = block.stateRoot;
eth_getProof(address, [], blockNumber)
这会返回:
accountProof(这是验证路径上所有节点的内容)账户在 MPT 中的值是 RLP 编码的四个字段:
accountRLP = rlp.encode([
nonce,
balance,
storageRoot,
codeHash
]);
MPT 中是按地址的 keccak256(address) 存的,所以路径是地址哈希。
accountKey = keccak256(address);
使用 Trie.verifyProof 方法来验证:
verifiedValue = Trie.verifyProof(stateRoot, accountKey, accountProof);
这一步会从 stateRoot 开始,走过 accountProof 里包含的每个节点数据,看能否重建出目标账户的值,并最终得到哈希匹配。
最后比对 verifiedValue 是否等于之前我们构造的 accountRLP 值。
如果一致,就表示:
✅ 此账户的状态确实存在于该区块的状态树中,数据可信、不可伪造!
| 节点类型 | 保存区块 | 保存状态 | 功能 |
|---|---|---|---|
| 完整节点 | ✅ | ✅ | 完整同步并验证所有交易 |
| 轻节点 | ❌ | ❌ | 只下载区块头,通过 Merkle Proof 验证状态 |
| 桥节点 | ✅ | ❌ | 一种混合型,仅用于桥接跨链 |
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!