# `EEVM`
[🔗](https://github.com/mw2000/eevm/blob/main/lib/eevm.ex#L1)

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

- `EEVM.Interpreter` — fetch-decode-execute loop and call frames
- `EEVM.Interpreter.MachineState` — frame-local state (pc, stack, memory, gas)
- `EEVM.Precompiles` — registered precompiles (`0x01`–`0x11`, `0x100`)
- `EEVM.Transaction` — envelope decoding, validation, signing, intrinsic gas
- `EEVM.Block.Processor` — end-to-end transaction-to-receipt pipeline
- `EEVM.Database`, `EEVM.WorldState`, `EEVM.Storage` — account and storage state
- `EEVM.MPT.Trie` + `EEVM.StateRoot` — Merkle-Patricia trie and state-root hash
- `EEVM.HardforkConfig` — per-hardfork EIP activation flags
- `EEVM.SystemContracts` — EIP-2935 (block hashes) and EIP-4788 (beacon roots)

# `disassemble`

```elixir
@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`

```elixir
@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`

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

Returns the list of logs emitted during execution.

# `logs_bloom`

```elixir
@spec logs_bloom(EEVM.Interpreter.MachineState.t()) :: EEVM.Block.Bloom.t()
```

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

# `stack_values`

```elixir
@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`

```elixir
@spec trace(
  binary(),
  keyword()
) :: {EEVM.Interpreter.MachineState.t(), EEVM.Tracer.t()}
```

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
