在了解完以太坊的区块结构之后,你是否有这么一个疑问:区块头里存了好多MPT树的根哈希,有账户状态树、交易树、收据树,还有账户状态里的存储合约账户数据的storage树。但这仅仅存储的是树的根哈希,那这些树本身存储到哪里去了呢?
我们先来回顾下0628那篇讲梅克尔树的文章。
在比特币的区块头里,仅有一棵简单的梅克尔树的根哈希,这棵梅克尔树的原始数据就是该区块所包含的所有交易信息,虽然比特币的区块里并没有存储整棵梅克尔树,但是区块里存储了所有交易信息,只要你拥有一个完整的区块数据,你就可以根据梅克尔树的算法一步步算出这棵树的每一层的哈希值。
从前两天我们对以太坊区块的了解来看,它的区块体里只包含了交易信息和叔区块头。有了交易信息,再加上区块头里的交易树的树根,这效果也跟比特币类似,没啥问题。
但是,另外的几棵树,它们的原始数据并没有存储到区块上。那是不是意味着,就算你拥有完整的以太坊区块信息,你也不知道以太坊的所有账户状态是什么样,产生了哪些收据信息,以及智能合约存储了哪些数据? 当然不是,如果这样的话,那还叫啥区块链啊。
我们仔细想想,其实在以太坊的交易信息里,有发送者的账户地址,接收者的账户地址,还有智能合约的原始代码和调用情况,所以,根据交易信息,然后按照以太坊的交易原理和EVM执行规则,就可以完整复盘出所有账户的状态。
但是,每次一有需求,比如就简单查一个账户的余额,就要去复盘整个交易历史,这显然太不方便。所以,以太坊直接存储了这些数据,只不过不是在区块上。
在以太坊每个节点上,都有一个levelDB数据库,所有的信息,包括区块信息、账户状态、交易信息等等,都会以key/value对的方式存储在这个数据库里。
比如,区块头的key是由区块头前缀(表示这是区块头的key)、区块号、区块hash构成,而value就是区块头的RLP编码值;区块体的key由区块体前缀(表示这是区块体的key)、区块号、区块hash构成,而value就是区块体的RLP编码。
以太坊的账户状态信息,则由一个专门的模块(stateDB)存储,每一个账户就是一个stateObject,key是账户地址的哈希值,value是账户信息的RLP