This is a basic easy to understand EVM implementation in rust - it handles most of the essential opcodes. It's suitable for learning EVM internals and running simple bytecode programs.
- Stack Operations: Proper 256-bit stack with Result-based error handling
- Memory Operations: MLOAD, MSTORE, MSIZE with automatic expansion
- Storage Operations: SLOAD, SSTORE with warm/cold access tracking
- ADD (0x01) - Addition
- MUL (0x02) - Multiplication
- SUB (0x03) - Subtraction
- DIV (0x04) - Division
- SDIV (0x05) - Signed division
- LT (0x10) - Less than
- GT (0x11) - Greater than
- EQ (0x14) - Equality
- AND (0x16) - Bitwise AND
- OR (0x17) - Bitwise OR
- XOR (0x18) - Bitwise XOR
- POP (0x50) - Pop from stack
- PUSH1-PUSH32 (0x60-0x7f) - Push values onto stack
- MLOAD (0x51) - Load 32 bytes from memory
- MSTORE (0x52) - Store 32 bytes to memory
- MSIZE (0x59) - Get memory size
- SLOAD (0x54) - Load from storage
- SSTORE (0x55) - Store to storage
- JUMP (0x56) - Unconditional jump
- JUMPI (0x57) - Conditional jump
- JUMPDEST (0x5b) - Jump destination marker
- CALLDATALOAD (0x35) - Load call data
- CALLDATASIZE (0x36) - Get call data size
- CALLDATACOPY (0x37) - Copy call data to memory
- RETURN (0xf3) - Return data
- REVERT (0xfd) - Revert execution
- STOP (0x00) - Stop execution
- SELFDESTRUCT (0xff) - Self destruct
- CALL (0xf1) - Call contract (stub)
- LOG0-LOG4 (0xa0-0xa4) - Log operations (simplified)
use mini_evm::evm::EVM;
use ethnum::U256;
let program = vec![
0x60, 0x0a, // PUSH1 10
0x60, 0x14, // PUSH1 20
0x01, // ADD
0x00, // STOP
];
let mut evm = EVM::new(program, 1000000, 0, vec![]);
match evm.run() {
Ok(()) => println!("Execution successful"),
Err(e) => println!("Error: {}", e),
}