1. 默克尔树

1.1. 默克尔证明

1.1.1. 默克尔路径

默克尔路径指的是某个输入值到默克尔根节点之间所有哈希值的集合。下图显示了输入值 “Peach” 的默克尔路径:

4.png

-"Peach" 的默克尔路径-

1.1.2. 默克尔证明

默克尔证明指的是不需要知道一个数据集合中的其他值就能证明某个值属于这个集合。

5.png

-默克尔证明-

默克尔证明需要三样东西:输入值(红色标记)、中间支哈希值(绿色标记)和默克尔根节点(蓝色标记)。每个输入值对应的中间支哈希值集合各不相同。

区块链系统经常会用到默克尔证明,证明某个数据集合内存在某个输入值,这样就不需要将整个数据集合都存储在区块链上了。假设一个以太币合约内有一个白名单列表, 只允许列表内的账户购买以太币。如果将白名单内每个账户信息都存储在区块链上,势必要付出很高的成本。在这种情况下,只需要创建一个默克尔树,再将根节点存储在区块链上即可。

例如,如果将根节点存储在一个智能合约上,这个智能合约很容易就能证明某个账户包含在白名单内:这个账户需提供中间支哈希值(合约所有者通过某种链下方式提供给账户持有者),智能合约将这个账户的哈希值依次与中间支哈希值进行哈希计算。如果最后得出的结果与默克尔根节点一致的话,就证明这个账户确实在白名单里。

请注意最后两张图中默克尔路径和默克尔证明的哈希值之间的关系。在同一棵树的同一个层级中,默克尔证明的哈希值与默克尔路径的哈希值是相互关联的。由此可见,默克尔证明能够重塑输入值的默克尔路径,这就是为什么最终结果是默克尔根节点的原因。

至此,可以看出默克尔证明具有以下特征:

  • 在链上存储默克尔证明所需的空间远远小于直接存储输入值所需的空间

  • 在链上公开存储默克尔证明也不会暴露整个输入值集合

  • 要证明某个输入值集合内是否存在某个值,验证默克尔证明的成本低于核对整个输入值集合的成本

1.1.3. ETH 中的默克尔实现

  1. 世界状态树包括了从地址到账户状态之间的映射。 世界状态树的根节点哈希值由区块保存(在 stateRoot 字段),它标示了区块创建时的当前状态。整个网络中只有一个世界状态树。

  2. **账户存储树保存了与某一智能合约相关的数据信息。**由账户状态保存账户存储树的根节点哈希值(在 storageRoot 字段)。每个账户都有一个账户存储树。

  3. **交易树包含了一个区块中的所有交易信息。**由区块头(在 transactionsRoot 区域)保存交易树的根节点哈希值。每个区块都有一棵交易树。

  4. **交易收据树包含了一个区块中所有交易的收据信息。**同样由区块头(在 receiptsRoot 区域)保存交易收据树的根节点哈希值;每个区块都有对应的交易收据树。

我们今天讨论的对象有:

  1. 世界状态: 以太坊这台分布式计算机的硬盘。它是从地址到账户状态的映射。

  2. 账户状态: 保存着每个以太坊账户的状态信息。账户状态同样保存着账户状态树的 storageRoot,后者包含了该账户的存储数据。

  3. 交易: 标示了系统中的状态转移。它可以是资金的转移、消息调用或是合约的部署。

  4. 区块: 包括对前序区块(parentHash)的链接,并且保存了当执行时会在系统中产生新状态的交易。区块同时保存了 stateRoot 、transactionRoot 、 receiptsRoot 、 世界状态树的根节点哈希、交易树以及对应的交易收据树。

我想用一张图来表示文中提及的各种概念信息。

4

-区块、交易、账户状态对象以及以太坊的默克尔树-

1.2. Reference