I implemented the Ethereum Virtual Machine from scratch in Typescript. The only external dependency is the
ethereum-cryptography
package used for the keccak256 hash function.
The EVM is the core of the Ethereum protocol. It is a stack-based virtual machine that executes bytecode and updates the glogbal state according to the rules described in the Ethereum Yellow Paper. The EVM is responsible for executing smart contracts and is what makes Ethereum a "World Computer".
W1nt3r.eth is the creator of the EVM From Scratch challenge, which consists in a series of 116 tests that need to be passed sequentially in order to have a working EVM implementation. The challenge is a great way to learn about the EVM and how it works. I highly recommend it if you want to really understand what is going on under the hood of Ethereum smart contracts.
- Day 0: Research of relevant learning material & tools to get started
- Day 1: Gathering more resources & reading Mastering Ethereum chapter 13
- Day 2: Setting up the EVM-from-scratch challenge & EVM class
- Day 3: Reading the yellow paper & EVM inception (EVM inside EVM)
- Day 4: Stack & memory implementation & first Opcodes
- Day 5: PUSH, POP, SUB Opcodes, MachineState context struct
- Day 6: Most Arithmetic, Comparison, Bitwise operations & JUMP Opcodes
- Day 7: Memory structure & related Opcodes
- Day 8: TxData, globalState, Block data & related Opcodes
- Day 9: More Environmental Opcodes & CALLDATALOAD. "Officially" started the challenge!
- Day 10: CALLDATASIZE, CALLDATACOPY, CODESIZE, CODECOPY Opcodes
- Day 11: EXTCODESIZE, EXTCODECOPY, SELFBALANCE Opcodes
- Day 12: Research & study on the Storage / data layer of the Ethereum protocol
- Day 13: Simple Storage implementation, SSTORE, SLOAD, RETURN, REVERT Opcodes
- Day 14: Upgraded test file & refactored code, added GAS, LOG Opcodes
- Day 15: Major EVM class refactoring & started CALL Opcode
- Day 16: Final CALL implementation & RETURNDATASIZE, RETURNDATACOPY Opcodes
- Day 17: Opcode runners refactoring, DELEGATECALL, STATICCALL Opcodes
- Day 18: CREATE, SELFDESTRUCT Opcodes. Challenge completed!
Get started by cloning the repo and installing the node dependencies:
git clone https://github.com/nicolas-racchi/evm-from-scratch.git
cd evm-from-scratch/evm-from-scratch-challenge
yarn
I added a command-line script to allow running the EVM with a simple command. If you want to run simple bytecode input (without passing any transaction data or block data), you can use the following command:
yarn start:bytecode <your-bytecode-input>
# example:
yarn start:bytecode 604260005260206000F3
If you want to provide additional runtime data, you can use the input.json file in the root directory as a template for the expected input format. You can then run the file content with the following command:
yarn start:file input.json
The program will output the step-by-step execution in a file under the evm-from-scratch-challenge/logs
directory.
This command will run all challenge-related tests:
yarn test
- W1nt3r.eth for creating the EVM From Scratch challenge.