From 2489ccf5451a4bc1f536da8c8faaef3078688607 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sun, 25 Feb 2018 16:48:32 -0500 Subject: [PATCH 1/4] comparison tables for EVM opcodes to ewasm methods and wasm instructions --- evm_vs_ewasm_opcode_table.md | 120 +++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 evm_vs_ewasm_opcode_table.md diff --git a/evm_vs_ewasm_opcode_table.md b/evm_vs_ewasm_opcode_table.md new file mode 100644 index 00000000..d1dd1433 --- /dev/null +++ b/evm_vs_ewasm_opcode_table.md @@ -0,0 +1,120 @@ +## EVM opcodes vs ewasm methods + +These tables compares EVM opcodes with ewasm methods and wasm instructions. The EVM defines 134 opcodes (as of the Byzantium hard fork). Of these 134 opcodes, some are generic machine instructions (ADD, MUL, ISZERO, XOR, etc.) and the rest are Ethereum-specific opcodes (SLOAD, SSTORE, CALLVALUE, BLOCKHASH, etc.). + +When EVM bytecode is translated into ewasm bytecode, the Ethereum-specific opcodes translate to ewasm interface methods (Ethereum Environment Interface (EEI) methods). These interface methods are provided as "host functions" to the wasm VM. All other EVM opcodes are not Ethereum-specific and do not access data from the Ethereum environment, so they can be translated to plain wasm instructions. + +To reference EVM opcodes, try the [yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf), the [readable yellow paper](https://github.com/chronaeon/beigepaper/blob/master/beigepaper.pdf), or the [pyethereum implementation](https://github.com/ethereum/pyethereum/blob/develop/ethereum/opcodes.py). + +To reference ewasm interface methods, see the [EEI spec](https://github.com/ewasm/design/blob/master/eth_interface.md). + + +### EVM opcodes that translate to ewasm methods (Ethereum Environment Interface (EEI) methods) + +EVM opcode | ewasm interface method +----------------------|----------------------------- +0x30: ADDRESS | getAddress +0x31: BALANCE | getBalance +0x32: ORIGIN | getTxOrigin +0x33: CALLER | getCaller +0x34: CALLVALUE | getCallValue +0x35: CALLDATALOAD | callDataCopy(resultOffset, dataOffset, 32) +0x36: CALLDATASIZE | getCallDataSize +0x37: CALLDATACOPY | callDataCopy(resultOffset, dataOffset, size) +0x38: CODESIZE | getCodeSize +0x39: CODECOPY | codeCopy +0x3a: GASPRICE | getTxGasPrice +0x3b: EXTCODESIZE | getExternalCodeSize +0x3c: EXTCODECOPY | externalCodeCopy +0x3d: RETURNDATASIZ | getReturnDataSize +0x3e: RETURNDATACOP | returnDataCopy +0x40: BLOCKHASH | getBlockHash +0x41: COINBASE | getBlockCoinbase +0x42: TIMESTAMP | getBlockTimestamp +0x43: NUMBER | getBlockNumber +0x44: DIFFICULTY | getBlockDifficulty +0x45: GASLIMIT | getBlockGasLimit +0x54: SLOAD | storageLoad +0x55: SSTORE | storageStore +0x58: PC | - +0x5a: GAS | getGasLeft +0xa0: LOG0 | log(0,..) +... | +0xa4: LOG4 | log(4,..) +0xf0: CREATE | create +0xf1: CALL | call +0xf2: CALLCODE | callCode +0xf3: RETURN | return +0xf4: DELEGATECALL | callDelegate +0xfa: STATICCALL | callStatic +0xfd: REVERT | revert +0xff: SELFDESTRUCT | selfDestruct + + + +## EVM opcodes vs WebAssembly instructions + +Whereas EVM is an untyped VM with a 256-bit word size, WebAssembly is a typed VM with 32-bit and 64-bit word sizes. The two wasm base types are integers and floats, which when combined with the two word sizes, create four types: i32, i64, f32, f64. + +Ethereum WebAssembly, or ewasm, is a subset of wasm. Only the integer types (i32 and i64) are supported, floating point types and floating point instructions are not supported. In total, 60 wasm instructions are supported in ewasm: +* 10 control flow instructions +* 11 basic instructions +* 19 integer arithmetic instructions +* 10 integer comparison instructions +* 3 integer conversion instructions +* 7 memory instructions (load, store, extend) + +ewasm excludes the wasm floating point instructions: +* 14 floating point arithmetic instructions +* 6 floating point comparison instructions +* 7 floating point conversion instructions + +To reference wasm instructions, see the [wasm spec](https://github.com/WebAssembly/design/blob/master/Semantics.md) or [reference manual](https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#instructions). + + +### EVM opcodes that translate to wasm instructions + +EVM opcode | wasm instruction (i32/i64) +----------------------|---------------------- +0x00: STOP | end +0x01: ADD | i32.add +0x02: MUL | i32.mul +0x03: SUB | i32.sub +0x04: DIV | i32.div_u +0x05: SDIV | i32.div_s +0x06: MOD | i32.rem_u +0x07: SMOD | i32.rem_s +0x08: ADDMOD | - +0x09: MULMOD | - +0x0a: EXP | - +0x0b: SIGNEXTEND | - +0x10: LT | i32.lt_u +0x11: GT | i32.gt_u +0x12: SLT | i32.lt_s +0x13: SGT | i32.gt_s +0x14: EQ | i32.eq +0x15: ISZERO | i32.eqz +0x16: AND | i32.and +0x17: OR | i32.or +0x18: XOR | i32.xor +0x19: NOT | - +0x1a: BYTE | - [i32.load8] +0x20: SHA3 | - +0x50: POP | drop +0x51: MLOAD | i32.load +0x52: MSTORE | i32.store +0x53: MSTORE8 | i32.store +0x56: JUMP | br +0x57: JUMPI | br_if, br_table +0x59: MSIZE | current_memory +0x5b: JUMPDEST | block, loop +0xfe: INVALID | unreachable +0x60: PUSH1 | i32.const +... | +0x7f: PUSH32 | i32.const +0x80: DUP1 | get_global, get_local +... | +0x8f: DUP16 | get_global, get_local +0x90: SWAP1 | - +... | +0x9f: SWAP16 | - From 5f680e12739c0927e0ce82c3abb549cf3e690fda Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sun, 25 Feb 2018 17:24:05 -0500 Subject: [PATCH 2/4] link for wasm host function --- evm_vs_ewasm_opcode_table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm_vs_ewasm_opcode_table.md b/evm_vs_ewasm_opcode_table.md index d1dd1433..ed731aa8 100644 --- a/evm_vs_ewasm_opcode_table.md +++ b/evm_vs_ewasm_opcode_table.md @@ -2,7 +2,7 @@ These tables compares EVM opcodes with ewasm methods and wasm instructions. The EVM defines 134 opcodes (as of the Byzantium hard fork). Of these 134 opcodes, some are generic machine instructions (ADD, MUL, ISZERO, XOR, etc.) and the rest are Ethereum-specific opcodes (SLOAD, SSTORE, CALLVALUE, BLOCKHASH, etc.). -When EVM bytecode is translated into ewasm bytecode, the Ethereum-specific opcodes translate to ewasm interface methods (Ethereum Environment Interface (EEI) methods). These interface methods are provided as "host functions" to the wasm VM. All other EVM opcodes are not Ethereum-specific and do not access data from the Ethereum environment, so they can be translated to plain wasm instructions. +When EVM bytecode is translated into ewasm bytecode, the Ethereum-specific opcodes translate to ewasm interface methods (Ethereum Environment Interface (EEI) methods). These interface methods are provided as [host functions](https://webassembly.github.io/threads/exec/runtime.html#syntax-hostfunc) to the wasm VM. All other EVM opcodes are not Ethereum-specific and do not access data from the Ethereum environment, so they can be translated to plain wasm instructions. To reference EVM opcodes, try the [yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf), the [readable yellow paper](https://github.com/chronaeon/beigepaper/blob/master/beigepaper.pdf), or the [pyethereum implementation](https://github.com/ethereum/pyethereum/blob/develop/ethereum/opcodes.py). From 8bab7e072565d20fdb7c9c103a510d1ef1c155e4 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Wed, 28 Feb 2018 20:36:11 -0500 Subject: [PATCH 3/4] use "reduce to", add footnotes --- evm_vs_ewasm_opcode_table.md | 39 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/evm_vs_ewasm_opcode_table.md b/evm_vs_ewasm_opcode_table.md index ed731aa8..e6cd9873 100644 --- a/evm_vs_ewasm_opcode_table.md +++ b/evm_vs_ewasm_opcode_table.md @@ -1,15 +1,15 @@ ## EVM opcodes vs ewasm methods -These tables compares EVM opcodes with ewasm methods and wasm instructions. The EVM defines 134 opcodes (as of the Byzantium hard fork). Of these 134 opcodes, some are generic machine instructions (ADD, MUL, ISZERO, XOR, etc.) and the rest are Ethereum-specific opcodes (SLOAD, SSTORE, CALLVALUE, BLOCKHASH, etc.). +These tables compares EVM opcodes with ewasm methods and wasm instructions. The EVM defines 134 opcodes (as of the Byzantium hard fork). Of these 134 opcodes, some represent generic machine instructions (ADD, MUL, ISZERO, XOR, etc.) and the rest are Ethereum-specific operations (SLOAD, SSTORE, GASPRICE, BLOCKHASH, etc.). -When EVM bytecode is translated into ewasm bytecode, the Ethereum-specific opcodes translate to ewasm interface methods (Ethereum Environment Interface (EEI) methods). These interface methods are provided as [host functions](https://webassembly.github.io/threads/exec/runtime.html#syntax-hostfunc) to the wasm VM. All other EVM opcodes are not Ethereum-specific and do not access data from the Ethereum environment, so they can be translated to plain wasm instructions. +When EVM bytecode is transpiled to ewasm bytecode, the Ethereum-specific opcodes translate to corresponding ewasm interface methods (Ethereum Environment Interface (EEI) methods). These interface methods are provided as [host functions](https://webassembly.github.io/threads/exec/runtime.html#syntax-hostfunc) to the wasm VM. All other EVM opcodes are not Ethereum-specific and do not access data from the Ethereum environment, so they reduce to pure wasm instructions. To reference EVM opcodes, try the [yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf), the [readable yellow paper](https://github.com/chronaeon/beigepaper/blob/master/beigepaper.pdf), or the [pyethereum implementation](https://github.com/ethereum/pyethereum/blob/develop/ethereum/opcodes.py). To reference ewasm interface methods, see the [EEI spec](https://github.com/ewasm/design/blob/master/eth_interface.md). -### EVM opcodes that translate to ewasm methods (Ethereum Environment Interface (EEI) methods) +### EVM opcodes with corresponding ewasm methods (Ethereum Environment Interface (EEI) methods) EVM opcode | ewasm interface method ----------------------|----------------------------- @@ -26,8 +26,8 @@ EVM opcode | ewasm interface method 0x3a: GASPRICE | getTxGasPrice 0x3b: EXTCODESIZE | getExternalCodeSize 0x3c: EXTCODECOPY | externalCodeCopy -0x3d: RETURNDATASIZ | getReturnDataSize -0x3e: RETURNDATACOP | returnDataCopy +0x3d: RETURNDATASIZE | getReturnDataSize +0x3e: RETURNDATACOPY | returnDataCopy 0x40: BLOCKHASH | getBlockHash 0x41: COINBASE | getBlockCoinbase 0x42: TIMESTAMP | getBlockTimestamp @@ -36,7 +36,7 @@ EVM opcode | ewasm interface method 0x45: GASLIMIT | getBlockGasLimit 0x54: SLOAD | storageLoad 0x55: SSTORE | storageStore -0x58: PC | - +0x58: PC | -[†](#f1) 0x5a: GAS | getGasLeft 0xa0: LOG0 | log(0,..) ... | @@ -51,6 +51,8 @@ EVM opcode | ewasm interface method 0xff: SELFDESTRUCT | selfDestruct +†. In EVM, the Program Counter (PC) opcode returns the currently executing bytecode position. When EVM is transpiled to ewasm with evm2wasm, this bytecode position is calculated by the transpiler and [inserted as a wasm constant](https://github.com/ewasm/evm2wasm/blob/80136977553c9b22e385f919fff808ef8a54be95/index.js#L247-L248). For ewasm code that is not transpiled from EVM, there is no interface method corresponding to the `PC` opcode. + ## EVM opcodes vs WebAssembly instructions @@ -72,9 +74,9 @@ ewasm excludes the wasm floating point instructions: To reference wasm instructions, see the [wasm spec](https://github.com/WebAssembly/design/blob/master/Semantics.md) or [reference manual](https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#instructions). -### EVM opcodes that translate to wasm instructions +### EVM opcodes that reduce to wasm instructions -EVM opcode | wasm instruction (i32/i64) +EVM opcode (256-bit) | wasm instruction i32/i64 (32-bit or 64-bit) ----------------------|---------------------- 0x00: STOP | end 0x01: ADD | i32.add @@ -84,10 +86,10 @@ EVM opcode | wasm instruction (i32/i64) 0x05: SDIV | i32.div_s 0x06: MOD | i32.rem_u 0x07: SMOD | i32.rem_s -0x08: ADDMOD | - -0x09: MULMOD | - -0x0a: EXP | - -0x0b: SIGNEXTEND | - +0x08: ADDMOD | -[‡](#f2) +0x09: MULMOD | -[‡](#f2) +0x0a: EXP | -[‡](#f2) +0x0b: SIGNEXTEND | -[‡](#f2) 0x10: LT | i32.lt_u 0x11: GT | i32.gt_u 0x12: SLT | i32.lt_s @@ -97,9 +99,9 @@ EVM opcode | wasm instruction (i32/i64) 0x16: AND | i32.and 0x17: OR | i32.or 0x18: XOR | i32.xor -0x19: NOT | - -0x1a: BYTE | - [i32.load8] -0x20: SHA3 | - +0x19: NOT | i32.sub (i32.const 0xffffffff) +0x1a: BYTE | i32.load8 +0x20: SHA3 | -[‡](#f2) 0x50: POP | drop 0x51: MLOAD | i32.load 0x52: MSTORE | i32.store @@ -115,6 +117,9 @@ EVM opcode | wasm instruction (i32/i64) 0x80: DUP1 | get_global, get_local ... | 0x8f: DUP16 | get_global, get_local -0x90: SWAP1 | - +0x90: SWAP1 | get_global, get_local ... | -0x9f: SWAP16 | - +0x9f: SWAP16 | get_global, get_local + + +‡. Some EVM opcodes, such as `ADDMOD` (modular addition), `EXP` (exponentiation), or `SHA3` (Keccak-256 hash), do not have simple reductions to single wasm instructions (or to only a few wasm instructions). The functionality of these opcodes is replicated by a relatively large wasm module (for instance, `SHA3` reduces to about [900 lines of wast code](https://github.com/ewasm/evm2wasm/blob/80136977553c9b22e385f919fff808ef8a54be95/wasm/keccak.wast)). From bf333f630514a792fbb9dc7d89a7dba6be8e9a2d Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sun, 24 Mar 2019 19:14:33 -0400 Subject: [PATCH 4/4] STOP -> finish, note EEI is at revision 4 --- evm_vs_ewasm_opcode_table.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evm_vs_ewasm_opcode_table.md b/evm_vs_ewasm_opcode_table.md index e6cd9873..88a94774 100644 --- a/evm_vs_ewasm_opcode_table.md +++ b/evm_vs_ewasm_opcode_table.md @@ -9,10 +9,11 @@ To reference EVM opcodes, try the [yellow paper](https://ethereum.github.io/yell To reference ewasm interface methods, see the [EEI spec](https://github.com/ewasm/design/blob/master/eth_interface.md). -### EVM opcodes with corresponding ewasm methods (Ethereum Environment Interface (EEI) methods) +### EVM opcodes (Byzantium) with corresponding ewasm methods (Ethereum Environment Interface (EEI) Revision 4) EVM opcode | ewasm interface method ----------------------|----------------------------- +0x00: STOP | finish(0, 0) 0x30: ADDRESS | getAddress 0x31: BALANCE | getBalance 0x32: ORIGIN | getTxOrigin @@ -44,7 +45,7 @@ EVM opcode | ewasm interface method 0xf0: CREATE | create 0xf1: CALL | call 0xf2: CALLCODE | callCode -0xf3: RETURN | return +0xf3: RETURN | finish 0xf4: DELEGATECALL | callDelegate 0xfa: STATICCALL | callStatic 0xfd: REVERT | revert @@ -78,7 +79,6 @@ To reference wasm instructions, see the [wasm spec](https://github.com/WebAssemb EVM opcode (256-bit) | wasm instruction i32/i64 (32-bit or 64-bit) ----------------------|---------------------- -0x00: STOP | end 0x01: ADD | i32.add 0x02: MUL | i32.mul 0x03: SUB | i32.sub