Skip to content

v0.1.0

Latest

Choose a tag to compare

@mw2000 mw2000 released this 12 Nov 13:26
37b89ee

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, and EEVM.Config.enabled?/2 says 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/2 runs bytecode as a message call. EEVM.call/4 and EEVM.create/3 call or deploy a contract from any address, like eth_call, with no key, nonce, or fees.

  • Transactions. EEVM.transact/4 validates and executes a signed transaction end to end: gas, refunds, coinbase fees, and a receipt. EEVM.Transaction.Signer signs, recovers senders, and turns a private key into an address; EEVM.Transaction.Envelope encodes and decodes the wire format.

  • Blocks. EEVM.Block.build/4, validate/3, and execute/4 build, 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/1 and decode/1 are the RLP codec, and EEVM.SystemContracts.genesis_accounts/1 sets up a new chain.

  • ABI and errors. EEVM.ABI encodes calls and decodes return data and logs. EEVM.revert_reason/1 decodes Error(string), Panic(uint256), and custom errors. Every error reason is listed, with a message, in EEVM.Error; details: true on EEVM.transact/4 returns the values a failed check compared.

  • State. The read-only EEVM.Database behaviour plugs in your own state backend, such as ETS or a node's JSON-RPC; use EEVM.Database makes a read-only adapter just four read callbacks. eevm keeps every write in an immutable overlay and returns it as EEVM.StateChanges. EEVM.Database.InMemory is built in.

  • Tracing. tracer: true on any entry point records an EIP-3155 trace; EEVM.Tracer.steps/1 and EEVM.Tracer.to_json/1 read it.

  • Simulation mode. EEVM.transact/4 takes an unsigned EEVM.TxEnv to run a transaction from any address, and EEVM.Config's disable_* switches relax the nonce, balance, base-fee, block-gas-limit, and EIP-3607 checks for tooling.

  • Custom precompiles through EEVM.Precompile and EEVM.Config.register_precompile/3.

  • Conformance. CI runs the official execution-spec-tests (v5.4.0, through Osaka) and ethereum/tests suites 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.Block refuses 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

  • @mw2000 made their first contribution in #1

Full Changelog: https://github.com/mw2000/eevm/commits/v0.1.0