EEVM — Ethereum Virtual Machine implementation in Elixir.

Execution engine targeting Cancun, with Prague and Osaka work in progress: full opcode set, all precompiles (including BLS12-381 via NIF), transaction validation and processing, MPT-backed state root, and harnesses for the official ethereum/tests suites. Conformance with those suites is still in progress, and many rules before Cancun are not yet gated per hardfork.

Quick Start

iex> result = EEVM.execute(<<0x60, 2, 0x60, 3, 0x01, 0x00>>)
iex> result.status
:stopped
iex> EEVM.stack_values(result)
[5]

Module Map

Summary

Functions

Disassembles bytecode into a human-readable list of instructions.

Executes EVM bytecode and returns the final machine state.

Returns the list of logs emitted during execution.

Computes the 256-byte logs bloom filter for the executed transaction.

Returns the stack contents as a list (top first).

Executes bytecode with an opcode-level tracer attached.

Functions

disassemble(bytecode)

@spec disassemble(binary()) :: [{non_neg_integer(), String.t(), String.t() | nil}]

Disassembles bytecode into a human-readable list of instructions.

Example

iex> EEVM.disassemble(<<0x60, 0x01, 0x60, 0x02, 0x01, 0x00>>)
[{0, "PUSH1", "0x01"}, {2, "PUSH1", "0x02"}, {4, "ADD", nil}, {5, "STOP", nil}]

execute(bytecode, opts \\ [])

@spec execute(
  binary(),
  keyword()
) :: EEVM.Interpreter.MachineState.t()

Executes EVM bytecode and returns the final machine state.

Options

  • :gas — initial gas limit (default: 1,000,000)

Example

iex> result = EEVM.execute(<<0x60, 0x0A, 0x60, 0x14, 0x01, 0x00>>)
iex> EEVM.stack_values(result)
[30]

logs(state)

@spec logs(EEVM.Interpreter.MachineState.t()) :: [map()]

Returns the list of logs emitted during execution.

logs_bloom(state)

Computes the 256-byte logs bloom filter for the executed transaction.

stack_values(state)

@spec stack_values(EEVM.Interpreter.MachineState.t()) :: [non_neg_integer()]

Returns the stack contents as a list (top first).

Convenience wrapper for inspecting results.

trace(bytecode, opts \\ [])

Executes bytecode with an opcode-level tracer attached.

Returns {final_state, tracer}. The tracer holds one TraceStep per executed opcode (see EEVM.Tracer). Use EEVM.Tracer.to_json/1 to emit a trace in EIP-3155 / geth --json format.

Example

iex> {state, tracer} = EEVM.trace(<<0x60, 0x01, 0x60, 0x02, 0x01, 0x00>>)
iex> state.status
:stopped
iex> length(EEVM.Tracer.steps(tracer))
4