Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OnchainEvm

Rust NIFs for Elixir: local EVM simulation via revm, Solidity ABI parsing via Alloy, debug/trace APIs, and contract codegen. Built on onchain.

Installation

Requires a Rust toolchain for NIF compilation.

def deps do
  [
    {:onchain, "~> 0.10"},
    {:onchain_evm, "~> 0.3"}
  ]
end

Modules

Module Purpose
Onchain.EVM Local EVM execution — fork mainnet state, simulate calls/transactions/batches
Onchain.Solidity Alloy-powered Solidity ABI parser (JSON ABI, .sol source, import resolution)
Onchain.Trace Debug/trace APIs — trace_transaction, trace_call, storage_at
Onchain.Contract.Generator .sol file → typed Elixir module at compile time

EVM Simulation

EVM simulation forks state from an RPC endpoint passed per-call via :rpc_url:

# Simulate a read (eth_call semantics)
Onchain.EVM.simulate_call(usdc_address, calldata, rpc_url: "https://eth-mainnet.example.com")

# Full execution result (gas_used, success, return data)
Onchain.EVM.simulate_transaction(address, calldata, rpc_url: url)

# Batch many calls against one shared fork
Onchain.EVM.simulate_batch(calls, rpc_url: url)

Options:

Option Meaning
:rpc_url RPC endpoint to fork from (required; validated — empty/non-HTTP(S)/hostless rejected)
:block Block to fork at — integer, "0x…" hex, or a tag ("latest", "finalized", "safe", "pending", "earliest")
:timeout_ms Per-RPC-request timeout (positive integer; default 30s, 5s connect). Surfaces as {:error, {:timeout, msg}}
:value, :gas_limit, :state_overrides Validated and threaded into the fork (invalid input fails fast, not silently dropped)

Every public function has a bang (!) variant that raises on error.

Contract Codegen

Generate a typed module from a .sol file or JSON ABI at compile time:

defmodule USDC do
  use Onchain.Contract.Generator, abi_file: "priv/abis/erc20.json"
end

USDC.balance_of(contract, holder, rpc_url: url)   # => {:ok, [balance]}

Generator inputs (in precedence order): :abi_json, :abi_file, :sol, :sol_file. Solidity sources support :remappings (Foundry-style) and :root_contract for import resolution.

Discovery

All modules use descripex for self-describing APIs:

OnchainEvm.describe()                     # Module overview
OnchainEvm.describe(:evm)                 # Function listings
OnchainEvm.describe(:evm, :simulate_call) # Full function details

Testing

mix test.json --quiet                        # Offline unit tests
mix test.json --quiet --include integration  # + integration (requires an RPC node)

Integration tests read ETHEREUM_API_URL (or ETH_RPC_URL).

License

MIT

About

EVM simulation, Solidity parsing, debug/trace APIs, and contract codegen for Elixir via Rust NIFs

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages