以太坊账户组织形式
在以太坊里,账户的状态数据最终是以键值对的形式存储在LevelDB
,所有的交易或者操作的结果,作为账户的状态(state)
存在,账户是以stateObject
体现,而所有的stateObject
都接授stateDB
的管理。
比较直观的表示就是这样:
我们按照StateObject
,Address
,StateDB
自底向上的顺序来看一下各部分的细节。
StateObject
一个以太坊账户对应的就是一个StateObject
,其中包含着很多非常有用的字段。
其中比较重要的字段有address
,data
,code
,trie
。
address
: 记录了合约的地址;data
: 保存了合约的余额,默克尔树根等一些元信息;code
: 以[]byte
的形式保存了合约的内容;trie
: 是StateObject
最为核心的字段,通过MPT
树来管理合约的数据;
在以太坊中有大量的账户,要找到这些账户就需要address
,stateDB
也是通过address
来管理这些账户的。
StateDB
StateDB
用来管理数量众多的账户。
其结构如下:
|
|
乍一看的反应是账户数据以一个map的形式存在stateObjects
字段里,但事实是账户的数据是存储在trie
中的,存储的形式和单个合约里状态的状态是一样的。
stateObjects
只是作为一个缓存,当创建,获得stateObject
的时候会添加进去,提升读取的性能。
我们知道这些账户数据最终是存储在LevelDB
中的,stateObjects
相当于一级缓存,如果查询不到,可以到trie
中查询,如果都查询不到就只能去查找数据库了。
StateDB
也支持快照和回滚操作,实现的比较简单,具体的数据在jornal
中,而快照的索引,需要回滚的时候只需求拿到索引暂存的数据反序列化回来就可以了。