Behaviour defining the external state interface for the EVM — account state (balances, nonces, code) plus per-contract storage — abstracted behind a single interface so different backends (in-memory, Merkle-backed, disk) can be plugged in without changing opcode implementations.
A database value is a %EEVM.Database{} struct containing:
impl— the module implementing@behaviour EEVM.Databasestate— the implementation-specific state (opaque to callers)
All public functions in this module dispatch to the impl module, passing
and receiving the opaque state. The default implementation is
EEVM.Database.InMemory.
Summary
Callbacks
Return all known account addresses in the backend state.
Return whether account at address is EIP-161 empty.
Check whether an account exists at the given address.
Remove an account entirely (used by SELFDESTRUCT under EIP-6780).
Fetch the full account record, or nil if the address has no state.
Return the balance in wei for address (0 if non-existent).
Return the bytecode deployed at address (empty binary if none).
Return the nonce for address (0 if non-existent).
Increment the nonce at address by 1.
Replace the entire account record at address.
Set the bytecode at address.
Set the balance at address.
Set the nonce at address.
Return addresses that currently have tracked storage entries.
Load a 256-bit storage slot for the given contract address.
Return all storage slots currently tracked for an address.
Store a 256-bit value into a storage slot for the given contract address.
Transfer amount wei from one address to another.
Functions
Wraps an implementation module and its initial state into a %Database{}.
Types
@type account() :: %{ optional(:balance) => non_neg_integer(), optional(:nonce) => non_neg_integer(), optional(:code) => binary(), optional(:storage) => EEVM.Storage.t() }
Callbacks
@callback account_addresses(state :: term()) :: [non_neg_integer()]
Return all known account addresses in the backend state.
@callback account_empty?(state :: term(), address :: non_neg_integer()) :: boolean()
Return whether account at address is EIP-161 empty.
@callback account_exists?(state :: term(), address :: non_neg_integer()) :: boolean()
Check whether an account exists at the given address.
@callback delete_account(state :: term(), address :: non_neg_integer()) :: term()
Remove an account entirely (used by SELFDESTRUCT under EIP-6780).
@callback get_account(state :: term(), address :: non_neg_integer()) :: account() | nil
Fetch the full account record, or nil if the address has no state.
@callback get_balance(state :: term(), address :: non_neg_integer()) :: non_neg_integer()
Return the balance in wei for address (0 if non-existent).
@callback get_code(state :: term(), address :: non_neg_integer()) :: binary()
Return the bytecode deployed at address (empty binary if none).
@callback get_nonce(state :: term(), address :: non_neg_integer()) :: non_neg_integer()
Return the nonce for address (0 if non-existent).
@callback increment_nonce(state :: term(), address :: non_neg_integer()) :: term()
Increment the nonce at address by 1.
@callback put_account(state :: term(), address :: non_neg_integer(), account :: account()) :: term()
Replace the entire account record at address.
@callback put_code(state :: term(), address :: non_neg_integer(), code :: binary()) :: term()
Set the bytecode at address.
@callback set_balance( state :: term(), address :: non_neg_integer(), balance :: non_neg_integer() ) :: term()
Set the balance at address.
@callback set_nonce( state :: term(), address :: non_neg_integer(), nonce :: non_neg_integer() ) :: term()
Set the nonce at address.
@callback storage_addresses(state :: term()) :: [non_neg_integer()]
Return addresses that currently have tracked storage entries.
@callback storage_load( state :: term(), address :: non_neg_integer(), key :: non_neg_integer() ) :: non_neg_integer()
Load a 256-bit storage slot for the given contract address.
@callback storage_slots(state :: term(), address :: non_neg_integer()) :: [ {non_neg_integer(), non_neg_integer()} ]
Return all storage slots currently tracked for an address.
@callback storage_store( state :: term(), address :: non_neg_integer(), key :: non_neg_integer(), value :: non_neg_integer() ) :: term()
Store a 256-bit value into a storage slot for the given contract address.
@callback transfer( state :: term(), from :: non_neg_integer(), to :: non_neg_integer(), amount :: non_neg_integer() ) :: {:ok, term()} | {:error, :insufficient_balance}
Transfer amount wei from one address to another.
Functions
@spec account_addresses(t()) :: [non_neg_integer()]
@spec account_empty?(t(), non_neg_integer()) :: boolean()
@spec account_exists?(t(), non_neg_integer()) :: boolean()
@spec delete_account(t(), non_neg_integer()) :: t()
@spec get_account(t(), non_neg_integer()) :: account() | nil
@spec get_balance(t(), non_neg_integer()) :: non_neg_integer()
@spec get_code(t(), non_neg_integer()) :: binary()
@spec get_nonce(t(), non_neg_integer()) :: non_neg_integer()
@spec increment_nonce(t(), non_neg_integer()) :: t()
Wraps an implementation module and its initial state into a %Database{}.
Example
db = Database.new(Database.InMemory, Database.InMemory.init())
@spec put_account(t(), non_neg_integer(), account()) :: t()
@spec put_code(t(), non_neg_integer(), binary()) :: t()
@spec set_balance(t(), non_neg_integer(), non_neg_integer()) :: t()
@spec set_nonce(t(), non_neg_integer(), non_neg_integer()) :: t()
@spec storage_addresses(t()) :: [non_neg_integer()]
@spec storage_load(t(), non_neg_integer(), non_neg_integer()) :: non_neg_integer()
@spec storage_slots(t(), non_neg_integer()) :: [ {non_neg_integer(), non_neg_integer()} ]
@spec storage_store(t(), non_neg_integer(), non_neg_integer(), non_neg_integer()) :: t()
@spec transfer(t(), non_neg_integer(), non_neg_integer(), non_neg_integer()) :: {:ok, t()} | {:error, :insufficient_balance}