Solidity智能合约开发 — 5.2 -理解EVM虚拟机交易执行、合约创建、区块上链
理解EVM虚拟机交易执行、合约创建、区块上链
1 EVM概述
一个交易数据中附加了合约创建代码或者合约函数调用代码,以太坊客户端就会相应的使用EVM来运行这些代码。所有智能合约代码最终反映为EVM机器码,以下是常有的EVM操作码.
1.1 EVM操作码
- 栈和内存操作码
POP PUSH MLOAD MSTORE JUMP PC MSIZE GAS DUP SWAP
- 通用系统操作码
CREATE CALL RETURN REVERT SELFDESTRUCT
- 算数操作码
ADD MUL SUB DIV SDIV MOD SMOD ADDMOD MULMOD EXP STOP
- 环境数据操作码
ADDRESS BALANCE CALLVALUE ORIGIN CALLER CODESIZE GASPRICE EXTCODESIZE RETURNDATACOPY
1.2 EVM代码执行
在EVM中,从逻辑上讲有两类程序代码
一类叫做“运行时字节码”,他们保存在ROM中,由各节点维护,且基于账户地址标识。
一类叫做“字节码”,仅在合约创建时执行一次,用来生成合约的“运行时字节码”的代码,不会持久化保存。
2 合约创建
合约创建可以由一个外部用户签名的交易执行触发,也可以在合约代码中由特定的合约代码所触发。对于EVM中执行合约,他需要若干输入参数。
- 发送者:直接发起合约创建操作的账户地址
- 原始交易发起人:触发当前执行、最初由外部用户签名的交易数据的发送者地址
- 可用gas: 创建过程中使用的最大gas数量
- gasPrice:触发当前执行、最初由外部用户签名的交易数据中指定的gas价格
- 初始捐款:发送到新创建合约的一定量以太币。
- EVM初始化代码:用来创建合约的“运行时字节码”
- 当前的运行栈深度
- 对状态进行修改的许可标志。
如果合约初始化代码的执行没有发生任何异常,那么由其所生成的合约“运行时字节码”会被保存到EVM的ROM中。此外还需要从发送者账号的balance中扣除执行这些初始化代码所消耗的gas费用和代码保存费用。
如果合约初始化代码的执行发生异常,那么将不会创建任何账户和任何金额转移。
3 消息调用
与合约创建一样,可以由一个外部用户签名的交易执行触发,也可以在合约代码中由特定的合约代码所触发。对于在EVM执行消息调用而言,也需要执行若干输入数据。
- 发送者:直接发起合约创建操作的账户地址
- 原始交易发起人:触发当前执行、最初由外部用户签名的交易数据的发送者地址
- 接收者:消息调用的目标地址
- 要执行的代码所在的账号地址:通常与接收者地址相同
- 可用gas: 创建过程中使用的最大gas数量
- gasPrice:触发当前执行、最初由外部用户签名的交易数据中指定的gas价格
- 初始捐款:发送到新创建合约的一定量以太币。
- 转账金额:发送到被调合约函数的以太币数量
- 当前的运行栈深度
- 对状态进行修改的许可标志。
在EVM中有4个操作码可以发起消息调用。
操作码 | 说明 |
CALL | 向某个接受者发起消息调用,recipient与sender可以相同,也可以不同 |
CALLCODE | 与CALL基本等价,但recipient与sender相同且与code address相同 |
DELEGATECALL | 与CALL基本等价,但recipent与sender相同且与code address不同 |
STATICCALL | 与CALL基本等级,但不允许转账,且不允许对状态进行任何修改 |
4 区块上链
看看区块如何最终定稿并添加到区块链中。
-
ommer验证
要求ommer区块的父区块必须是当前区块6代(含)以内的祖先区块。
-
交易验证
对于生成区块的矿工而言,他需要从本地维护的交易池中选择哪些gasPrice合适的交易来顺序执行,同时更改相应的状态和存储并生成交易收据数据。
对于非矿工全节点而言,除了顺序执行所有交易,同时更改本地维护的状态树、存储树,生成交易收据,并计算累计的gas消耗量与区块头中给定的gasUsed相符。
-
奖励发放
前期区块的beneficiary最多可获得1+2/32的基础区块奖励。
-
状态验证
对于生成区块的矿工而言,所有交易执行所导致的状态变动以及奖励发放之后的最终‘状态树’根节点哈希值保存到区块头的stateRoot字段。
对于非矿工全节点,则需要验证按区块中包含交易数据列表顺序执行完所有交易,并发放区块奖励之后的“状态树”根节点哈希值是否与区块头的stateRoot相符。
- 验证区块头数据的nonce和mixHash字段
对于矿工节点,就是基于Ethhas算法获得nonce和mixHash的值
对于非矿工节点,就是验证区块头中保存的这两个数据的一致性。
更多推荐
所有评论(0)