This is a project to recreate EVM in Python from scratch. Please do not use this in production applications.
The main goal of this project was to learn the inner workings of the EVM, its opcodes and architecture. This program only focuses on EVM and does not include a full Ethereum client (node) implementation. Consensus clients, Execution clients and interactions with the network are out of scope for this project.
The majority of work done was to create a bytecode processing machine that would resemble a real EVM and provide accurate results, given proper inputs. EVM architecture and opcode implementation were the main focus.
-
Install Python 3.8+
-
Install required pip packages ("eth-hash","simple-rlp","pickledb")
pip install eth-hash pip install simple-rlp pip install pickledb
-
Clone the repo
git clone https://github.com/theluxaz/Python-EVM.git
-
Run run.py after inserting values
python run.py
The main program loop is located at run.py. You can either run the provided EVM tests by setting "TESTING = True" or insert your own bytecode in hex in "hexcode" variable and set "TESTING" to False.
Please edit the execution context data and transaction data in "run.py" as you see fit for each run. The "ethereum network" state is located in variables EVM_STATE.db and EVM_STATE_TESTING.db (for testing).
- Stack
- Memory
- Storage
- Gas (Static)
- System
- Testing
- Stop and Arithmetic Operations
- Comparison & Bitwise Logic Operations
- SHA3
- Environmental Information
- Block Information
- Stack, Memory, Storage and Flow Operations
- Push Operations
- Duplication Operations
- Exchange Operations
- Logging Operations
- System operations
- Halt Execution, Mark for deletion Operations
- More testing and error handling
- Add block structure and block header history for BLOCKHASH
- Blockchain persistence via Merkle Patricia Trie
- Dynamic Gas
- Add validation
- Errors for edge cases
- Refactor and clean code
- Nonce rework
Set up architecture, file structure, listed all opcodes with their gas and mnemonics.
Implemented arithmetic, comparison and bitwise operation opcodes.
Implemented memory, storage, PUSH, DUP and SWAP opcodes.
Reworked stack to work with bytes, tested and fixed all the previously added opcode implementations. Added JUMP and GAS functionality.
Added functionality for both execution and transaction context. Added instruction related to them such as CALLDATACOPY or GASLIMIT. Added EXTCODESIZE, EXTCODECOPY and EXTCODEHASH.
Added functionality for ADDRESS and BALANCE. Added logging opcodes such as LOG0. Started refactoring the application to accommodate CREATE instructions.
Added functionality for testing opcodes from evm-from-scratch-challenge resources https://github.com/w1nt3r-eth/evm-from-scratch. Adjusted Executor to work with multiple contexts. Fixed errors present in certain opcode implementations.
Added many more opcodes which needed major refactoring, such as CALL, DELEGATECALL, RETURNDATACOPY etc. Reworked context nesting and reverting. Tested and fixed most implemented opcodes.
Finished all the remaining Opcodes such as CREATE, CREATE2 and SELFDESTRUCT. Made the EVM fully functional and tested. Code cleanup and refactoring needed.
Finished the project. Added persistence for Storage via "pickledb". Refactored and cleaned up the code. Still more refactoring to be done in the future.
Distributed under the MIT License.