图二、由指令执行触发的一种扩充虚拟机级的状态转换。EVM:以太坊虚拟机。
在区块链部署和执行之前,智能合约
必须编译为EVM字节码,并可能
通过多一个交易在以太坊中分配初始值。
EVM
是一个堆栈机器,如
清单2中
所示的已编译Wallet.sol的第2-6行中的典型堆栈操作操作码所示。 第9-
10
行涉及通
过
CALL
操作码发出的撤回内部消息调用。 特别令人感兴趣的是
GAS操作码。该指令反映了以
太坊的gas系统,其中指令执行和内存使用消耗gas [20],由其调用者账
户以以太币支付,由STARTGAS交易字段定义。
它的值有效地限制
了事务执
行允许执行的最大计算步骤数。
这个概念对于以太坊的反拒绝服务模型至关重要,可以
防止意外或恶
意的计算浪费
[18]
。反过来,
STARTGAS
由与以太坊
块相关的GASLIMIT值限制
[17]。 在指令执行之前,EVM检查执行指令所需的gas是否被添加到迄今为
止的总gas利用率中,超过分配给相应事务的最大gas,
当超过时触发气体
耗尽异常。通过在第
9
行执行
GAS
指令,可用气体的量被压入堆栈,作为后
续CALL指令的第一个参数。一般来说,需要与调用其他合约或向账户发
送以太币相关的指令,才能将一定量的gas转发给被调用者进行消费。天
然气价格由矿工市场驱动,交易
创建者指定天然气价格,矿工优先考虑价
格优惠的交易。一些网站,例如。
ETH Gas Station
1
帮助
交易创建者获得
正确的天然气价格。
2.2.
以太坊状态转换
当将以太坊视为状态机时,
Wallet.sol
的执行会
在三个级别上触发
状态转换:
EVM
指令,
事务和块挖掘。 在EVM层面,图。 2、合约的
持
久性存储和
EVM
的易失性存储器部分表征执行状态,而
EVM
指令触发转
换。
在所有外部调用和(对于某些)内部调用开始时创建一个新的状
态。只读数据部分存储调用的参数,其他事务数据,
1
https://ethgasstation.info/。
例如发送方的地址、以太币中的交易值以及区块相关的
上下文,例如block
的hash和timestamp合约存储也是可用的,在我们的示例中存储货币的
键值对。对它的任何更改最终都将在成功执行后的全局状态中反映出
来。 堆栈区域是最动态的,图。图3
示出了在
withdraw()的执行期间
由作用于堆栈顶部的一个NULL指令触发的状态转换。
事务级别的状态,图。 3,处于更高的抽象级别,并且忽略了EVM
级别。相反,它关注的是
更新以太坊全局状态的交易。 此状态是
外部拥有
的帐户和合约帐户的数组,后者与合约代码及其持久存储变量的唯一区
别。事务级状态转换,包括初始
事务和由此触发的任何内部事务,通过事务
字段(例如,目的地账户地址和
加密货币值字段)和合约代码执行。如果
一个交易调用Wallet.sol的取款函数,金额为1 Wei(1 Ether 10
18
Wei),则后状态会在货币映射中反映更新后的值
交易以块的形式执行,它们被存储为不可变的区块链,以保护全局
状态的完整性。 在块级,图。 4,执行状态由这些新接受
的事务块(
T
X)和相关联的块元数据定义,例如, 区块
哈希和链接到它的前一个区块
的哈希。该级别不
考虑由单个事务
或EVM级别状态转换生成的中间状
态,除了事务接收(RX)内的值或由合约代码生成的日志条目然而,通
过通常由以太坊节点提供的事务跟踪[21],
可以将事务执行重播到
EVM
指
令级别。 这
是通过区块链遍历和访问作为全局状态的一部分存储的合约字
节码来重新计算(或缓存)
trans-action
调用点
处的全局状态来实现的。全
局状态的完整性由一个称为状态根的散列保护,该散列存储为每个块的
一部分
2.3.
符号和执行语义
支持
Oyente
符号执行引擎的语义
[7]
在其他候选者中被选中[22,23],
因为它们为智能合约的所需模型提供了更方便的起点