在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。
假如有三个键:
apple
app
appricot
Trie 会这样存储它们👇:
(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,是否真实可信,不是伪造数据
stateRoot
stateRoot
是整棵账户状态树的根哈希。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 验证状态 |
桥节点 | ✅ | ❌ | 一种混合型,仅用于桥接跨链 |
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!