EchoEVM is a minimal, pedagogical Ethereum Virtual Machine (EVM) implementation written in Go. It focuses on transparent bytecode execution, traceability, and ease of experimentation rather than production consensus or networking features.
- What's New in v0.0.12
- Features
- Requirements
- Installation
- Quick Start
- CLI Commands
- ABI Encoding
- Testing
- Architecture
- Configuration
- Roadmap
- Contributing
- License
- Precompiled Contracts: Native support for ECRECOVER (0x01), SHA256 (0x02), RIPEMD160 (0x03), IDENTITY (0x04)
- Tuple ABI Encoding: Encode struct-like parameters using
(val1,val2,...)syntax - CALL Precompile Integration: Automatic precompile detection in CALL/STATICCALL opcodes
See ROADMAP.md for the complete version history.
| Category | Features |
|---|---|
| Execution | Constructor deployment, runtime calls, bytecode disassembly |
| ABI Support | Function selector encoding, primitives, arrays, bytes types |
| Tracing | JSON structured per-opcode tracing with pre/post state |
| Gas Metering | EIP-2929 compatible dynamic gas calculations |
| EIP Support | EIP-1153 (Transient Storage), EIP-5656 (MCOPY) |
| Precompiles | ECRECOVER, SHA256, RIPEMD160, IDENTITY (0x01-0x04) |
| Testing | Unit tests, integration tests, Ethereum compliance tests |
| Logging | Zerolog-based structured logging (plain/JSON output) |
- Go 1.23.2+
- (Optional)
solcfor compiling.solfiles directly
From source:
go install github.com/smallyunet/echoevm/cmd/echoevm@latestClone and build:
git clone https://github.com/smallyunet/echoevm.git
cd echoevm
make build
make install # install into GOPATH/binVerify:
echoevm --help# Simple arithmetic: PUSH1 1 PUSH1 2 ADD
echoevm run 6001600201
# With debug trace
echoevm run --debug 6001600201# Deploy constructor bytecode
echoevm deploy -a ./artifacts/Add.json --print
# Call a function with ABI encoding
echoevm call -a ./artifacts/Add.json -f add(uint256,uint256) -A 2,40
# Generate execution trace
echoevm trace -a ./artifacts/Add.json -f add(uint256,uint256) -A 7,9 --full | jq .echoevm repl
# Type opcodes: PUSH1 10 PUSH1 20 ADD| Command | Description |
|---|---|
run |
Execute raw bytecode with optional debug tracing |
deploy |
Run constructor and extract runtime bytecode |
call |
Execute runtime bytecode with ABI encoding |
trace |
JSON line trace of opcode execution |
disasm |
Disassemble bytecode to human-readable opcodes |
repl |
Interactive EVM shell |
version |
Display build metadata |
--log-level, -L Log level (trace|debug|info|warn|error)
--output, -o Output format (plain|json)
--config, -c Config file path (reserved)
--rpc-url Ethereum RPC endpoint
deploy - Execute constructor bytecode
echoevm deploy -a ./artifacts/Add.json --print
echoevm deploy -b ./constructor.bin --out-file runtime.bindisasm - Disassemble bytecode
# From hex
echoevm disasm 6001600201
# Output:
# 0000: PUSH1 01
# 0002: PUSH1 02
# 0004: ADD
# From artifact
echoevm disasm -a ./artifacts/Add.json --runtime
# JSON output
echoevm disasm -o json 6001600201call - Execute runtime bytecode
# With ABI encoding
echoevm call -a ./artifacts/Add.json -f add(uint256,uint256) -A 2,40
# With raw calldata
echoevm call -r ./runtime.bin -d 771602f70000...trace - Execution trace
# First 40 steps
echoevm trace -a ./artifacts/Add.json -f add(uint256,uint256) -A 1,2 --limit 40 | jq .
# Full pre/post state
echoevm trace -a ./artifacts/Loops.json -f forLoop(uint256) -A 5 --full | jq .Supported types for --function/--args encoding:
| Type | Examples |
|---|---|
| Integers | uint8, uint256, int128, etc. |
| Boolean | true, false |
| Address | 0x742d35Cc... (40 hex chars) |
| String | UTF-8 dynamic strings |
| Bytes | bytes (dynamic), bytes32 (fixed) |
| Arrays | uint256[], address[] |
Array syntax:
echoevm call -a ./artifacts/Sum.json -f sum(uint256[]) -A "[1;2;3;4;5]"
echoevm call -a ./artifacts/Multi.json -f send(address[]) -A "[0xabc...;0xdef...]"Note: Tuples and nested arrays are not yet supported.
make test # Run all tests (unit, integration, compliance)
make test-unit # Run Go unit tests
make test-integration # Run integration tests
make test-compliance # Run Ethereum compliance tests
make setup-tests # Download test fixtures (~100MB)echoevm/
βββ cmd/echoevm/ # CLI commands (deploy, call, trace, etc.)
βββ internal/
β βββ evm/
β β βββ core/ # Stack, memory, opcode table
β β βββ vm/ # Interpreter, opcode implementations
β βββ config/ # Constants, environment variables
β βββ logger/ # Zerolog wrapper
β βββ errors/ # Error definitions
βββ tests/ # Integration and compliance tests
βββ docs/ # Documentation
Arithmetic, Bitwise, Comparison, Stack, Memory, Storage, Control Flow, Environment, Call/Return/Revert, Logging, System.
See docs/CONFIGURATION.md and docs/LOGGING_GUIDE.md for details.
Environment variables:
export ECHOEVM_LOG_LEVEL=debug
export ECHOEVM_GAS_LIMIT=30000000
export ECHOEVM_ETHEREUM_RPC="https://mainnet.infura.io/v3/<key>"| Code | Meaning |
|---|---|
| 0 | Successful execution |
| 1 | Execution reverted (REVERT) |
| 2 | Invalid arguments / configuration error |
See ROADMAP.md for the complete development roadmap.
Upcoming:
- Tuple and nested array ABI support
- Fork-specific opcode behavior (Cancun)
- Improved compliance test coverage
- Web-based debugger UI
- Fork the repository
- Create a feature branch (
feat/<topic>) - Add/update tests
- Run
make testand ensure build is clean - Open a PR with clear description
Issues and discussions for roadmap ideas are welcome!
This project is open source under the MIT License. See LICENSE for details.
If you're using EchoEVM in research, experiments, or education, a citation or link back is appreciated.