虚拟机指令集

以太坊中虚拟机指令集的花费经过了精心考虑,在读与写的花费上作了平衡。重点区分了内存读写和区块(磁盘)读写两个档次的花费。在屡次版本修订中指令集的取舍也有凸显,下面列表举例说明一些重要的指令:

助记符 Gas 花费 移出Stack花费 添入Stack花费 注释
0x00 STOP 0 0 0 停止执行.
0x01 ADD 3 2 1 加法
0x02 MUL 5 2 1 乘法
0x03 SUB 3 2 1 减法
0x04 DIV 5 2 1 整除.
0x06 MOD 5 2 1 Mod除法取余
0x10 LT 3 2 1 小于
0x11 GT 3 2 1 大于
0x14 EQ 3 2 1 是否相等.
0x15 ISZERO 3 1 1 取反
0x16 AND 3 2 1 按位与操作
0x17 OR 3 2 1 按位或操作
0x18 XOR 3 2 1 按位异或操作
0x19 NOT 3 1 1 按位取反操作
0x20 SHA3 FORMULA 2 1 计算Keccak-256 哈希.
0x30 ADDRESS 2 0 1 当前执行账户的地址
0x31 BALANCE 400 1 1 执行账户的余额
0x32 ORIGIN 2 0 1 执行源自哪个账户地址
0x33 CALLER 2 0 1 呼叫方地址
0x35 CALLDATALOAD 3 1 1 获取当前环境输入值
0x36 CALLDATASIZE 2 0 1 获取当前环境输入值大小
0x37 CALLDATACOPY FORMULA 3 0 当前环境输入值拷贝入内存
0x38 CODESIZE 2 0 1 当前环境代码体积大小
0x39 CODECOPY FORMULA 3 0 拷贝当前环境代码进入内存
0x3b EXTCODESIZE 700 1 1 合约代码占用体积
0x3c EXTCODECOPY FORMULA 4 0 合约代码存入内存
0x40 BLOCKHASH 20 1 1 上一出块的哈希值
0x41 COINBASE 2 0 1 挖矿奖励地址.
0x42 TIMESTAMP 2 0 1 Block timestamp.
0x43 NUMBER 2 0 1 Block number.
0x44 DIFFICULTY 2 0 1 Block difficulty.
0x45 GASLIMIT 2 0 1 Block gas limit.
0x50 POP 2 1 0 Stack 抛出最上面的值
0x51 MLOAD 3 1 1 将1word 从内存读取出
0x52 MSTORE 3 2 0 将1 word 存入内存
0x53 MSTORE8 3 2 0 将1byte 存入内存
0x54 SLOAD 200 1 1 存储区取回 1 word 宽度值
0x55 SSTORE FORMULA 1 1 1 word 宽度数据存入存储区.
0x56 JUMP 8 1 0 跳转
0x5a GAS 2 0 1 剩余 gas 值
0x60 – 0x7f PUSH* 3 0 1 将值推送入堆栈
0x80 – 0x8f DUP* 3 “*” “* + 1” 复制堆栈上某个值
0x90 – 0x9f SWAP* 3 “* + 1” “* + 1” 交换堆栈上两个值
0xa0 LOG0 FORMULA 2 0 创建一个log 日志
0xf0 CREATE 32000 3 1 创建合约(贵)
0xf1 CALL FORMULA 7 1 调用智能合约
0xf2 CALLCODE FORMULA 7 1 调用智能合约,重新设置调用方信息
0xf3 RETURN 0 2 0 返回
0xf4 DELEGATECALL FORMULA 6 1 调用智能合约,并允许被叫方更改自己的存储区(危险)
0xff SELFDESTRUCT FORMULA 1 0 摧毁合约,退出所有以太币

这张表里面有好些指令与我们前文的 Stack、Memory、Storage存储相关且相对应 [1] :

  • MSTORE/MSTORE8 :按照 256bit 或者 8bit 执行内存的存入操作。
  • MLOAD : 按照 256bit 执行内存的读取操作。
  • SLOAD/STOR:按照 256bit 执行存储的读取、存入操作。
  • PUSH/SWAP : 按照 256bit 执行堆栈的读取,交换操作。
[1]标注 * 的都和源头数据大小有关