Crate evm

Source
Expand description

§Ethereum Virtual Machine in Rust

Rust EVM is a flexible Ethereum Virtual Machine interpreter that can be easily customized.

§Basic usage

If you want to simply run EVM against Ethereum mainnet, use the evm-mainnet crate.

The entrypoint of a normal EVM execution is through the transact function. The transact function implements a hybrid (stack-based, and then heap-based) call stack.

To use the transact function, you will need to first implement a backend. This is anything that implements interpreter::runtime::RuntimeEnvironment, and interpreter::runtime::RuntimeBackend traits. You will also need to select a few other components to construct the invoker parameter needed for the function.

  • Select an Invoker. The invoker defines all details of the execution environment except the external backend. standard::Invoker is probably want you want if you are not extending EVM.
  • For the standard invoker, select a standard::Config, which represents different Ethereum hard forks.
  • Select the precompile set. You may want the StandardPrecompileSet in evm-precompile crate.
  • Select a resolver. This defines how the interpreter machines are resolved given a code address for call or an init code for create. You may want standard::EtableResolver, which accepts a precompile set.

§Debugging

Rust EVM supports two different methods for debugging. You can either single step the execution, or you can trace the opcodes.

§Single stepping

Single stepping allows you to examine the full machine internal state every time the interpreter finishes executing a single opcode. To do this, use the heap-only call stack HeapTransact. Parameters passed to HeapTransact are the same as transact.

§Tracing

The interpreter machine uses information from an interpreter::etable::Etable to decide how each opcode behaves. The default implementation is interpreter::etable::DispatchEtable. interpreter::etable::DispatchEtable is fully customizable and a helper function is also provided interpreter::etable::DispatchEtable::wrap.

If you also want to trace inside gasometers, simply create a wrapper struct of the gasometer you use, and pass that into the invoker.

§Customization

All aspects of the interpreter can be customized individually.

Re-exports§

pub use evm_interpreter as interpreter;

Modules§

backend
Backend-related traits and implementations
standard
Standard machines and gasometers

Structs§

HeapTransact
Heap-based call stack for a transaction. This is suitable for single stepping or debugging. The hybrid version transact uses a heap-based call stack internally after certain depth.

Enums§

InvokerControl
Control for an invoker.
MergeStrategy
Merge strategy of a backend substate layer or a call stack gasometer layer.

Traits§

GasMutState
Mutable GasState. This simply allows recording an arbitrary gas.
Invoker
An invoker, responsible for pushing/poping values in the call stack.

Functions§

transact
Initiate a transaction, using a hybrid call stack.