以太坊源码分析—账户的管理
前言
以太坊是一个巨大的状态机,在网络中,每一个全节点都保存着以太坊状态机的全部历史,只要愿意,我们可以查询到任何时刻的状态
(黄皮书中World State
),而账户状态便是其中的状态,这部分功能由主要由代码中的state
包提供
基本概念
账户地址
在以太坊中,无论是外部账户
还是合约账户
,都以一个160bit
的数组表示地址,它是由特定椭圆曲线上的一个点表示的公钥经过Keccak Hash
算法截取而来
关于椭圆曲线,请点击椭圆曲线
关于账户之间的区别,请点击外部账户和合约账户的区别
账户内容
以太坊中,一个账户用Account
表示
type Account struct { Nonce uint64 Balance *big.Int Root common.Hash CodeHash []byte }
各个字段的意义如下:
Nonce
:账户发起交易的次数Balance
:账户的余额Root
[合约]:代表存储空间的一棵MPT
树的根节点的Hash
,可以简单地理解为一片存储空间,可以用它存储一些数据到区块链上,关于MPT
,可以查看这篇博文。CodeHash
[合约]:合约代码的Hash值
注:[合约]表示该项仅对合约账户有效
账户在区块链中的位置
所有账户以MPT树的形式组织起来,根节点的Hash值存储在区块Header
的stateRoot
字段
账户管理
stateDB & stateObject
在以太坊账户管理中,stateObject
表示一个账户的动态
变化,结构中的关键字段如下
type stateObject struct { address common.Address data Account db *StateDB trie Trie code Code ...... }
address
为账户的160 bits 地址data
为账户的信息,即前面提到的Account结构trie
合约账户的存储空间的缓存,我们可以从由data的Root从底层数据库中读取这棵树,但鉴于我们会经常使用,所以把它缓存起来也不是一个坏主意code
合约代码的缓存,作用和trie类似
stateDB
表示所有账户的动态
变化,它管理stateObject
,结构中的关键字段如下:
type stateDB struct { db Database trie Trie stateObjects map[common.Address] * stateObject ...... }
db
以太坊底层数据库接口,账户的信息都是从数据库中读取的trie
所有账户组织而成的的MPT树的实例,从它里面可以读取以太坊所有账户stateObjects
管理的所有需要修改的stateObject
账户操作
在执行区块中的交易时,我们可能需要修改某些账户的信息(比如增减余额,或者修改合约账户代码) ,这时我们按以下步骤进行操作
- 从
stateDB
找到账户对应的stateObject
,若不存在,则从trie
树中,通过读取底层数据库构建新的stateObject
,访问过的stateObject
会缓存起来 - 对
stateObject
账户进行操作,可能会涉及对余额的操作,如AddBalance()
调用,也有可能对存储空间的操作,如SetState()
,或者对合约代码的操作如SetCode()
- 在区块构建完成时,计算每个账户新的
MPT
树的各个节点Hash
,并存入数据库,完成修改。
相关推荐
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-28
源码zanqunet 2020-10-26
一叶梧桐 2020-10-14
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
lzzyok 2020-10-10
anchongnanzi 2020-09-21
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18
zhujiangtaotaise 2020-08-18
xiemanR 2020-08-17