This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
ZEVM is a high-performance Ethereum Virtual Machine (EVM) implementation written in Zig. It is a port of the Rust revm implementation, providing:
- Complete EVM Implementation: Full support for Ethereum protocol up to Prague hardfork
- Production-Ready Precompiles: All 18 standard Ethereum precompiled contracts implemented
- Cross-Platform Support: Works on macOS, Linux, and Windows with static linking
- Type-Safe Design: Leverages Zig's compile-time guarantees for safety and performance
The project maintains 100% feature parity with the Rust revm reference implementation, verified through comprehensive testing and comparison.
# Build using Makefile (recommended - auto-detects OS and installs deps)
make
make build # Build only
make install-deps # Install dependencies only
make test # Run all tests
make clean # Clean build artifacts
# Manual Zig build commands
zig build # Build all targets
zig build test # Run tests
zig build -Dblst=false # Build without blst library
zig build -Dmcl=false # Build without mcl library
# Build specific examples
zig build precompile_example
zig build zevm-test
zig build zevm-bench- macOS: Uses Homebrew for dependencies (
/opt/homebrew/include) - Linux: Uses apt-get/dnf for dependencies (
/usr/local/include) - Windows: Uses vcpkg (see CROSS_PLATFORM.md)
The Makefile automatically detects the OS and installs dependencies accordingly.
The project follows a modular architecture mirroring revm's structure:
src/primitives/: Core types (U256, Address, Hash), constants, and hardfork definitionssrc/bytecode/: Opcode definitions, bytecode analysis, and EIP-7702 supportsrc/state/: Account info, storage, and state transitionssrc/database/: Pluggable database interface with in-memory implementationsrc/context/: Block, transaction, and configuration managementsrc/interpreter/: Stack-based EVM interpreter with gas trackingsrc/precompile/: All 18 Ethereum precompiled contractssrc/handler/: Transaction execution orchestrationsrc/inspector/: Debugging and profiling tools
- Modular Structure: Each module is self-contained with a
main.zigentry point - Static Linking: All crypto libraries (
blst,mcl) are statically linked for self-contained binaries - Spec-Based Execution: Hardfork support via
SpecIdenum, with precompiles adapting gas costs per spec - Error Handling: Uses Zig's error union types (
PrecompileError,InstructionResult, etc.) - Memory Safety: Leverages Zig's memory management (no GC, explicit allocators)
- PrecompileId: Union enum identifying precompiles, supports Custom variants
- PrecompileSpecId: Enum for hardfork specs (Homestead, Byzantium, Istanbul, Berlin, Cancun, Prague, Osaka)
- Database Interface: Pluggable state storage (see
src/database/main.zig) - Inspector Interface: Hooks for transaction tracing and debugging
- Context: Manages execution state, environment, and configuration
All 18 standard Ethereum precompiles are implemented:
- Identity (0x04): Data copy
- SHA256 (0x02): SHA-256 hash function
- RIPEMD160 (0x03): RIPEMD-160 hash function
- ECRECOVER (0x01): Elliptic curve signature recovery (libsecp256k1)
- ModExp (0x05): Modular exponentiation (Byzantium/Berlin/Osaka variants)
- BN254 (0x06-0x08): BN254 curve operations (mcl library)
- Blake2F (0x09): Blake2 compression function
- KZG Point Evaluation (0x0A): KZG commitment verification (blst library)
- BLS12-381 (0x0B-0x11): All 7 BLS12-381 precompiles (blst library)
- P256Verify (0x100): secp256r1 signature verification (OpenSSL)
- PrecompileId.name(): Returns EIP-7910 standardized names
- PrecompileId.precompile(): Gets spec-appropriate precompile implementation
- PrecompileId.Custom: Support for custom precompile identifiers
- Gas Cost Adaptation: Precompiles automatically adjust gas costs based on hardfork
- libsecp256k1: ECRECOVER precompile (typically via package manager)
- OpenSSL: P256Verify precompile (typically via package manager)
- blst: BLS12-381 and KZG operations (built from source or installed)
- mcl: BN254 operations (built from source or installed)
- Makefile: Automatically installs dependencies via OS-specific package managers
- build.zig: Handles linking and include paths for all libraries
- Static Linking: All binaries statically link
blstandmclfor portability - Fallback: Libraries can be disabled with
-Dblst=falseor-Dmcl=false
See CROSS_PLATFORM.md and DEPENDENCIES.md for detailed installation instructions.
This project is a port of revm (Rust EVM). When implementing new features:
- Check revm first: Look at
revm/crates/for reference implementation - Maintain parity: Ensure behavior matches revm exactly
- Test vectors: Use Ethereum test suite and revm's test cases
- Documentation: See
PRECOMPILE_FEATURE_PARITY.mdfor comparison
- Memory Management: Zig uses explicit allocators, no RAII
- Error Handling: Zig error unions vs Rust Result types
- Generics: Zig uses
comptimefor compile-time polymorphism - Pattern Matching: Zig uses
switchexpressions instead ofmatch
- Unit Tests: Each module has comprehensive unit tests (
src/precompile/tests.zig) - Integration Tests: Full EVM execution tests (
src/test.zig) - Precompile Tests: 73+ unit tests covering all precompiles
- Gas Cost Verification: Tests verify gas costs match revm exactly
- Cross-Platform: CI runs tests on both Ubuntu and macOS
make test # Run all tests via Makefile
zig build test # Run tests via Zig build system
zig test src/test.zig # Run specific test filebuild.zig: Main Zig build configuration, handles library linkingMakefile: Cross-platform build automation and dependency managementsrc/version.zig: Version information and release metadata
README.md: Main project documentationCHANGELOG.md: Version history and changesRELEASE_NOTES.md: Detailed release notesCROSS_PLATFORM.md: Platform-specific build instructionsDEPENDENCIES.md: Dependency installation guidePRECOMPILE_FEATURE_PARITY.md: Comparison with revm implementation
revm/: Rust reference implementation (submodule or copy)- Used for understanding behavior and maintaining parity
- Modules:
snake_casefor file names (main.zig,secp256k1.zig) - Types:
PascalCasefor structs, enums, unions (PrecompileId,PrecompileResult) - Functions:
camelCasefor public functions (precompile,execute) - Constants:
UPPER_SNAKE_CASEfor module-level constants (P256VERIFY,BYZANTIUM)
- Use Zig error unions:
PrecompileResult = union(enum) { success: PrecompileOutput, err: PrecompileError } - Return errors explicitly:
return PrecompileResult{ .err = PrecompileError.OutOfGas } - Use
tryfor error propagation
- Use explicit allocators:
std.heap.c_allocatorfor global, or pass allocators to functions - Prefer stack allocation when possible
- Use
std.ArrayListfor dynamic arrays
// Define precompile constant
pub const PRECOMPILE = main.Precompile.new(
main.PrecompileId.Sha256,
main.u64ToAddress(2),
sha256Run,
);
// Implementation function
pub fn sha256Run(input: []const u8, gas_limit: u64) main.PrecompileResult {
const gas_cost = main.calcLinearCost(input.len, 60, 12);
if (gas_cost > gas_limit) {
return main.PrecompileResult{ .err = main.PrecompileError.OutOfGas };
}
// ... implementation
return main.PrecompileResult{ .success = main.PrecompileOutput.new(gas_cost, result) };
}- Fixed ModExp Osaka gas calculation to match EIP-7883
- Fixed EIP-7823 input size limits (1024 bytes)
- Added PrecompileId.Custom variant and convenience methods
- Verified Fusaka upgrade parity with revm
- Maintain feature parity with revm
- Keep up with Ethereum hardfork changes
- Ensure cross-platform compatibility
- Optimize performance where possible
- Create implementation file in
src/precompile/ - Add PrecompileId variant in
src/precompile/main.zig - Register in appropriate spec in
Precompiles.forSpec() - Add tests in
src/precompile/tests.zig - Update
PRECOMPILE_FEATURE_PARITY.md
- Check revm implementation for reference
- Update gas calculation function
- Add tests for new gas costs
- Verify against Ethereum test suite
- Check
build.zigfor platform-specific logic - Update
Makefileif needed - Test on target platform
- Update
CROSS_PLATFORM.mdif instructions change
- Reference Implementation: Check
revm/crates/for Rust implementation - Ethereum Specs: See EIPs and Ethereum execution specs
- Zig Documentation: https://ziglang.org/documentation/
- Build Issues: See
CROSS_PLATFORM.mdandDEPENDENCIES.md