以太坊 状态树 和 存储树
在 账户探秘 中,已经详细讲述了账户和世界状态的概念,我们一起来回想一下,账户的集合组成了世界状态,而账户在组成世界状态时正采用了 MPT 树的组织形式。
每个账户都处在树的叶子节点上,树的组织则按照排列顺序进行串联哈希,最终层层哈希得出世界状态。当更改某单一账户时,则会引发它所在分支的上层哈希值的更改,直到影响到根节点的哈希值,根节点的哈希值称为状态树(stateRoot),这个值将存入区块头部。世界状态随着区块链的前进而不断变化,状态树的值也不断变更。
下图中最右侧抽象地代表了一棵状态树,它保存了全球所有以太坊的账户的状态(MPT棵树的形式)。回忆 账户探秘 的知识,以太坊账户分为外部账户和合约账户两种。这棵树的每个叶子节点就代表了一个账户。
存储树,账户状态,世界状态的构成关系
放大右侧树中,叶子节点的内容,看到上图的中间,可以看到一个账户的结构,其包含了四个域。
[nonce, balance, storageRoot(可选), codeHash(可选)]
根据以太坊黄皮书,账户若是一个智能合约账户,则必定包含了 存储树 (storageRoot)和 代码存储 (codeHash)。
若我们继续放大观察存储树,即为上图最左边的树。存储树保存了智能合约的变量数据,它维持着256位的变量数据索引与RLP 算法编码过的256位数据本身。
为保证数据完整性,这些数据 也被组织成一棵 MPT 树的形式 。该MPT树的根节点哈希值称为 存储树 。
存储树 是账户状态的一个 域 ,该值随着合约的存储区的增加、删除、改动而不断变更。
代码存储 是只读的,它是合约账户的所执行的代码,它在合约第一次创建完毕后就不可以再变更。
每个区块都有一棵独立的 交易树 (transactionsRoot),这棵树包含了当前区块打包的所有交易。交易的排列顺序由矿工在打包时唯一确定。若有幸包同一个块中含了同一个账户发出的数笔交易,矿工按照发送账户的 nonce ...