Repository navigation
The first release. eevm is an Ethereum Virtual Machine written in pure Elixir and embedded as a library: it runs EVM bytecode, signed transactions, and whole blocks, for every mainnet fork from Frontier to Osaka.
Added
-
Forks. Frontier through Osaka, chosen with
EEVM.Config.new(fork, chain_id: id)(default:cancun). Every rule is gated on the EIP that introduced it, andEEVM.Config.enabled?/2says whether an EIP is active. -
Notable EIPs. EIP-1559 fees, EIP-2718 and EIP-2930 typed transactions, EIP-4844 blobs with KZG point evaluation, EIP-7702 set-code transactions, EIP-2929 warm and cold access, EIP-1153 transient storage, EIP-6780 SELFDESTRUCT, EIP-2537 BLS12-381 precompiles, and from Osaka EIP-7825 (transaction gas limit cap), EIP-7918 (blob base fee bound), EIP-7934 (block size limit), EIP-7939 (CLZ), EIP-7951 (P256VERIFY), and EIP-7823 and EIP-7883 (ModExp bounds and pricing). The README lists them all.
-
Running code.
EEVM.run/2runs bytecode as a message call.EEVM.call/4andEEVM.create/3call or deploy a contract from any address, likeeth_call, with no key, nonce, or fees. -
Transactions.
EEVM.transact/4validates and executes a signed transaction end to end: gas, refunds, coinbase fees, and a receipt.EEVM.Transaction.Signersigns, recovers senders, and turns a private key into an address;EEVM.Transaction.Envelopeencodes and decodes the wire format. -
Blocks.
EEVM.Block.build/4,validate/3, andexecute/4build, check, and apply blocks, including withdrawals, the EIP-4788 and EIP-2935 system calls, EIP-7685 requests, receipts, logs bloom, and the state, transaction, and receipt roots.EEVM.Block.encode/1anddecode/1are the RLP codec, andEEVM.SystemContracts.genesis_accounts/1sets up a new chain. -
ABI and errors.
EEVM.ABIencodes calls and decodes return data and logs.EEVM.revert_reason/1decodesError(string),Panic(uint256), and custom errors. Every error reason is listed, with a message, inEEVM.Error;details: trueonEEVM.transact/4returns the values a failed check compared. -
State. The read-only
EEVM.Databasebehaviour plugs in your own state backend, such as ETS or a node's JSON-RPC;use EEVM.Databasemakes a read-only adapter just four read callbacks. eevm keeps every write in an immutable overlay and returns it asEEVM.StateChanges.EEVM.Database.InMemoryis built in. -
Tracing.
tracer: trueon any entry point records an EIP-3155 trace;EEVM.Tracer.steps/1andEEVM.Tracer.to_json/1read it. -
Simulation mode.
EEVM.transact/4takes an unsignedEEVM.TxEnvto run a transaction from any address, andEEVM.Config'sdisable_*switches relax the nonce, balance, base-fee, block-gas-limit, and EIP-3607 checks for tooling. -
Custom precompiles through
EEVM.PrecompileandEEVM.Config.register_precompile/3. -
Conformance. CI runs the official execution-spec-tests (v5.4.0, through Osaka) and
ethereum/testssuites on every push. The Conformance table has the counts and the exceptions. -
No native code. All cryptography is Elixir, from Keccak-256, secp256k1, and P-256 to BN254, BLS12-381, and KZG: no NIFs, no Rust, and no OTP
:crypto.
Known limitations
- The DAO fork's irregular state change (EIP-779) isn't implemented, so 3 legacy blockchain fixtures fail (#183).
- 9 stress-test fixtures are skipped in CI because they run past its timeout: 50,000 STATICCALLs (to SHA-256 and other precompiles), a 1 MB call at depth 1,024, and BLAKE2F at maximum rounds (#201, #224).
- eevm is young and not proven in production. Think twice before relying on it where consensus correctness matters. The simulation switches are never for consensus, and
EEVM.Blockrefuses a config that sets one. - The API is pre-1.0 and may change in a minor version. Some names from before this release remain as deprecated delegates, whose compiler warnings name the replacement.
What's Changed
- Add GitHub Actions CI workflow by @mw2000 in #1
- Add gas metering to EVM execution by @mw2000 in #2
- Add persistent storage (SLOAD/SSTORE) by @mw2000 in #3
- Add environment opcodes and ExecutionContext by @mw2000 in #4
- Split ExecutionContext into Transaction, Block, Contract by @mw2000 in #5
- Add PUSH0 (EIP-3855) and KECCAK256 opcodes by @mw2000 in #6
- Modularize executor into opcode modules and reorganize project structure by @mw2000 in #7
- chore: Add logo to README by @mw2000 in #8
- Add MCOPY memory copy opcode (EIP-5656) by @mw2000 in #21
- Add RETURNDATACOPY opcode by @mw2000 in #20
- Add LOG0–LOG4 event logging opcodes by @mw2000 in #19
- Implement CODECOPY opcode by @mw2000 in #22
- Implement EXTCODESIZE, EXTCODECOPY, and EXTCODEHASH opcodes by @mw2000 in #23
- Implement call stack and execution frames by @mw2000 in #24
- Implement CREATE and CREATE2 opcodes by @mw2000 in #26
- Implement CALL opcode by @mw2000 in #25
- Refactor runtime structure and add quality tooling by @mw2000 in #27
- Implement STATICCALL opcode by @mw2000 in #29
- Implement DELEGATECALL and CALLCODE opcodes by @mw2000 in #28
- Implement TLOAD/TSTORE transient storage opcodes (EIP-1153) by @mw2000 in #49
- Implement contract size limits (EIP-170/EIP-3860) by @mw2000 in #51
- Implement BLOBHASH and BLOBBASEFEE opcodes (EIP-4844/EIP-7516) by @mw2000 in #50
- Implement precompile routing in CALL path — Closes #34 by @mw2000 in #53
- Implement cold/warm access list tracking (EIP-2929) — Closes #38 by @mw2000 in #54
- Implement SELFDESTRUCT opcode (EIP-6780) — Closes #32 by @mw2000 in #52
- feat(precompiles): add RIPEMD-160 precompile (address 0x03) by @mw2000 in #57
- feat(precompiles): add identity precompile (address 0x04) by @mw2000 in #55
- feat(precompiles): add SHA-256 precompile (address 0x02) by @mw2000 in #56
- feat(precompiles): add Blake2f precompile (address 0x09) by @mw2000 in #60
- feat(precompiles): add ModExp precompile (address 0x05) by @mw2000 in #58
- feat(precompiles): add ecrecover precompile (address 0x01) by @mw2000 in #59
- feat(precompiles): add KZG point evaluation precompile (0x0A) by @mw2000 in #62
- feat(precompiles): add BN256 curve precompiles (0x06, 0x07, 0x08) by @mw2000 in #61
- feat(gas): implement SSTORE gas schedule (EIP-2200 + EIP-3529) by @mw2000 in #63
- feat(gas): add gas refund counter by @mw2000 in #64
- refactor: improve documentation, structure, and naming conventions by @mw2000 in #65
- feat(selfdestruct): implement EIP-6780 same-transaction deletion semantics by @mw2000 in #66
- Add Merkle Patricia Trie implementation with official Ethereum test vectors by @mw2000 in #67
- feat: Add Database behaviour with swappable backend interface by @mw2000 in #68
- feat: Add 2048-bit logs bloom filter per Yellow Paper §4.3.1 by @mw2000 in #71
- feat: Add transaction validation with intrinsic gas calculation by @mw2000 in #69
- feat: Add transaction type structs, envelope encoding/decoding, and sender recovery by @mw2000 in #70
- feat(gas): add intrinsic calldata gas module with EIP-2028 constants by @mw2000 in #96
- feat(machine_state): pre-warm COINBASE address in access set by @mw2000 in #95
- feat(opcodes): reject 0xEF code prefix in CREATE/CREATE2 by @mw2000 in #94
- feat(precompile): add custom precompile registration API by @mw2000 in #98
- feat(state): wire MPT state root computation by @mw2000 in #97
- feat(eip-161): implement empty account clearing by @mw2000 in #99
- feat: add hardfork configuration system by @mw2000 in #100
- Add initial official StateTest harness by @mw2000 in #101
- feat: Add Elixir StateTest fetch workflow by @mw2000 in #102
- docs: add @moduledoc to all undocumented modules by @mw2000 in #103
- Implement calldata cost floor (EIP-7623) by @mw2000 in #104
- Implement BLS12-381 precompiles (EIP-2537) by @mw2000 in #105
- ci: fix BLS NIF load failures on cache restore by @mw2000 in #108
- feat(tracer): opt-in opcode-level execution tracing (EIP-3155) by @mw2000 in #107
- Implement set-code transactions (EIP-7702) by @mw2000 in #106
- feat: implement beacon block root contract (EIP-4788) by @mw2000 in #109
- feat: implement historical block hashes contract (EIP-2935) by @mw2000 in #110
- feat: add block-level transaction processor by @mw2000 in #111
- feat: add transaction receipt module with EIP-2718 encoding by @mw2000 in #113
- feat: add end-to-end transaction execution pipeline by @mw2000 in #112
- refactor: revm-style layering (Interpreter / Handler / Block) by @mw2000 in #114
- refactor: extract child-frame merge into EEVM.Interpreter.Journal by @mw2000 in #115
- refactor: merge EEVM.Receipt into EEVM.Block.Receipt by @mw2000 in #116
- chore: remove tracked .DS_Store files and ignore them by @mw2000 in #117
- feat(test): add BlockchainTest harness (ValidBlocks + InvalidBlocks + TransitionTests) by @mw2000 in #118
- chore: polish mix.exs and add ExDoc + Pages workflows by @mw2000 in #129
- chore: align with community Elixir style guide by @mw2000 in #130
- refactor: drive opcode dispatch from the Registry by @mw2000 in #131
- refactor(machine_state): split into Frame / Env / Substate by @mw2000 in #132
- refactor(test-support): unify StateTest/BlockchainTest tx execution (#127) by @mw2000 in #133
- refactor: unify parent_hash representation as binary (#128) by @mw2000 in #134
- refactor(block): fold withdrawals into Block.Processor by @mw2000 in #135
- chore(docs): trim moduledocs — drop EVM Concepts and Elixir Learning Notes by @mw2000 in #136
New Contributors
Full Changelog: https://github.com/mw2000/eevm/commits/v0.1.0