EVM 1.0 transpiler, evacuated from NSA/Microsoft

Alex Beregszaszi 2bdcb3b6a0 Merge pull request #305 from ewasm/generator-add-gaslimit hace 7 años
bin d1d4959c62 Don't silently swallow async errors hace 7 años
cmake 0be02c1c86 Upgrade to binaryen 1.37.35 hace 7 años
docs 949bea3b16 Update docs hace 7 años
include 6ffbbf7251 Change evm2wasm/evm2wast to require a vector and introduce evmhex2wasm/evmhex2wast to support the old functionality hace 7 años
libs ca2fad2ac3 Do not output names section with binaryen hace 7 años
samples eef5219369 Added samples hace 7 años
tests 00cf2c5915 Remove unused wabt opt hace 7 años
tmp fdec4382c9 Rekindle with ewasm-kernel hace 7 años
tools 7b8b3ca8dc Do not output new line in the evm2wasm CLI hace 7 años
wasm 0022c42eed Regenerate interface hace 7 años
.gitignore fdec4382c9 Rekindle with ewasm-kernel hace 7 años
.gitmodules 72807ad85c fix stack trace hace 8 años
CMakeLists.txt 27c944c16e CMake: Add option to disable building tools hace 7 años
LICENSE 7cb21b704c update docs hace 8 años
README.md f63a338948 Briefly describe how generateInterface works hace 7 años
circle.yml 7e66c48f8c Disable tracing on circleci (to speed up the test) hace 7 años
index.js c99ce41b9a Replace special handling of i64 for CALL with a dedicated gasLimit type (64bit) hace 7 años
node-cpp-build-env.dockerfile ff2124985d circleci: run state tests with Hera hace 7 años
opcodes.js 8013697755 Rename SUICIDE to SELFDESTRUCT hace 7 años
package.json 75cab64df0 chore(package): update documentation to version 7.0.0 hace 7 años

README.md

SYNOPSIS

CircleCI js-standard-style

EVM (Ethereum VM 1.0) to eWASM transcompiler. Here is a online frontend.

INSTALL

Clone the repository and run npm install

USE

There is a commandline tool to transcompile EVM input:

Transcompile EVM to WASM

$ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file`

Transcompile EVM to WAST

$ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` --wast

Transcompile EVM to WAST with embedded EVM trace statements for each transpiled EVM opcode

$ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` --wast --trace

Transcompile EVM to WAST with gas metering per transpiled EVM opcode (not per branch segment)

$ bin/evm2wasm.js -e `evm_bytecode_file` -o `wasm_output_file` --wast --charge-per-op

DEVELOP

  • After any changes to .wast file, npm run build needs to be run to compile the files into a .json file
  • To rebuild the documentation run npm run build:docs
  • To lint run npm run lint
  • And make sure you test with npm test and npm run vmTests which runs the offical Ethereum test suite

The above build command will invoke wasm/generateInterface.js which generates wasm/wast.json containing a Webassembly function corresponding to each EVM opcode.

The core logic of the evm2wasm compiler is in index.js, which iterates the input EMV bytecode and generates a Webassembly output by invoking each of the above generated Webassembly functions and concatenating them into the output.

API

./docs/

TECHNICAL NOTES

EVM is stack based and offers access to memory, storage and state via special instructions.
Here we replicate the stack layout in WebAssembly (WASM) and implement each operation working on this stack.

OPCODES

Every opcode (bar some special instructions) receives the current stack pointer ($sp) as i32 and must return the adjusted stack pointer.

STACK LAYOUT

The stack grows from memory location 0, where 256 bit values are stored linearly in LSB byteorder.
The $sp points to the starting position of the top stack entry (and not the next free stack position). If the stack is empty, it is set to -32.

MEMORY LAYOUT

The resulting (after transpilation) contract memory layout is currently as follows:

.---------------------------------------------------
| Reserved space for the stack (32768 bytes)
| - each stack entry is 256 bits
| - the stack is limited to 1024 entries
+---------------------------------------------------
| Word count (4 bytes)
| (Number of 256 bit words stored in memory)
+---------------------------------------------------
| Previous memory cost in word count (4 bytes)
| (The cost charged for the last memory allocation)
+---------------------------------------------------
| Scratch space (32 bytes)
+---------------------------------------------------
| Reserved space for the Keccak-256 context (1024 bytes)
+---------------------------------------------------
| "EVM 1.0" contract memory starts here ("unlimited" in size)
`---------------------------------------------------

METERING

The generated eWASM contract contains gas metering. It is assumed evm2wasm will become a deployed trusted contract, which returns eWASM code that does not need to be run through the gas injector contract.

LICENSE

MPL-2.0