Solidity智能合约开发 — 5.1 -理解EVM虚拟机状态、交易、收据和区块

EVM是以太坊协议核心组件之一,有独立的指令集、内存、存储和其他一些相关要素。以太坊可以看作一个由交易所驱动的状态机。

1 状态

以太坊的所有操作和数据都是根据“账户”来区分和标识的,以太坊的账号(无论是外部账户还是合约账户)都会有一个4字段所组成的数据元组来表示其状态。其账户状态如下表:

表5-1 账户状态字段结构
字段名称 描述
nonce 如果nonceHash为空,这个值等于由此账户所发出的所有交易数量;如果nonceHash为某段EVM代码的哈希值,则这个值等于由此账户所创建的合约数量
balance 等于该账户所拥有的以太token数量,以wei为单位
storageRoot 用于保存账户全局唯一的存储树根节点哈希值
codeHash 与此账户相关联的EVM代码哈希值

2 交易

交易时触发状态变动的唯一途径。交易数据的字段结构如下:

表5-2 交易数据的字段结构
字段名称 描述
nonce 由交易发送者所发出的所有交易数量
gasPrice 执行这个交易所需要计算不住消耗的每单位gas的价格
gasLimit 执行这个交易的最大gas数量,在交易开始前设置,设定后不能再增加
to 消息调用接收者地址,对于合约创建交易,此字段为空
value 转移到接受者账户的wei数量
v 一个用来构成交易签名的第65字节长度数据
r 一个用来构成交易签名的第1-32字节长度数据
s 一个用来构成交易签名的第33-64字节长度数据
data 这个交易为“合约创建”时,其数据被认为是账户初始化程序的EVM代码,当这个交易为“消息调用”时,其数据被认为是合约函数调用数据(ABI编码)

3 收据

        区块数据中有一个字段是receiptRoot, 他的值是这个区块中所有交易的“收据(receipt)”所组成的树(tie)的根节点哈希值。每一个区块都有一个独立的收据树,树的整体数据由各节点分别维护,只把这个树的根节点哈希值保存到区块中。

        每个交易的交易收据都是一个有4个元素的元组。

  • 交易执行之后的状态树根节点哈希值(medState)
  • 区块中当前交易执行完成后的累计gas使用量。
  • 交易过程中创建的日志(log)集合。
  • 由交易日志所构成的Bloom过滤器。

此外,我们可以定义事件的代码中将某个事件参数声明为indexed;指定将这个参数的值放入Bloom过滤器,对于这些指定为indexed的事件参数,我们就可以通过JSON-RPC或者Web3接口的filter功能对其实际值进行查找过滤。

4 区块

以太坊的区块有3个部分组成:block header、transaction list和Ommer Block Header

表5-4 区块头数据的字段结构
parentHash 父区块头的keccak256哈希值
ommerHash 当前区块的ommers列表的kaccak256哈希值
beneficiary 成功挖到这个区块所得到的所有交易费的160位接受地址
stateRoot 所有交易被执行完且区块定稿后的状态树的根节点的keccak256哈希值
transactionsRoot 当前区块中所有交易所组成的树的根节点的keccak256哈希值
receiptsRoot 当前区块中所有交易的收据所组成的树的根节点的keccak256哈希值
logsBloom 当前区块中所有交易的收据数据中的可索引信息组成的Bloom过滤器
difficulty 当前区块难度水平的纯量值
number 当前区块的祖先数量(创世区块这个值为0,其他是区块的顺序号
gasLimit 目前每个区块的gas开支上限
gasUsed 当前区块的所有交易所用掉的gas之和
timestamp 当前区块初始化的unix时间戳
extraData 与当前区块相关的任意字节数据
mixHash 256位的哈希值,用来与nonce一起证明当前区块已经承载了足够的计算量
nonce 64位的哈希值,用来与mixHash一起证明当前区块已经承载了足够的计算量

猜你喜欢

转载自blog.csdn.net/qincheng168/article/details/126332498