虚拟机指令集¶
以太坊中虚拟机指令集的花费经过了精心考虑,在读与写的花费上作了平衡。重点区分了内存读写和区块(磁盘)读写两个档次的花费。在屡次版本修订中指令集的取舍也有凸显,下面列表举例说明一些重要的指令:
值 | 助记符 | 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] | 标注 * 的都和源头数据大小有关 |