Onchain.Solidity (onchain_evm v0.3.0)

Copy Markdown View Source

Solidity ABI parser powered by Alloy and solang-parser via Rustler NIF.

Supports three input modes:

  • ABI JSON — standard solc output. Parses function signatures, selectors, parameter types, events, and errors. Use parse_abi_json/1.
  • Solidity source — raw source strings. Recovers structs, enums, NatSpec, and constants that ABI JSON discards. Use parse_sol/1.
  • Resolved Solidity files — root .sol files with relative imports and Foundry-style remappings. Use resolve_sol_file/2 or parse_sol_file/2.

Output Structure

Both parsers return maps with :functions, :events, :errors, :constructor. The Solidity parser additionally returns :structs, :enums, and :constants, and attaches :natspec to each function entry.

Parameter Maps

All parameter maps use :ty (not :type) for the Solidity type string. Nested struct/tuple parameters include :components with recursive param() maps.

Selectors & Topics

Selectors and topic hashes are 0x-prefixed hex strings (e.g. "0x70a08231"), consistent with the Onchain.Hex convention used throughout the codebase.

The :return_type field on each function produces tuple-type strings compatible with Onchain.ABI.decode_response/2 (e.g. "(uint256,uint256,bool)").

Error Format

SourceError Shape
Invalid JSON / malformed ABI{:error, {:parse_error, reason}}
Invalid Solidity source{:error, {:parse_error, reason}}
File not found / unreadable{:error, {:file_error, reason}}

Functions

FunctionPurpose
parse_abi_json/1Parse ABI JSON string → structured map
parse_abi_json!/1Same, raises on error
parse_abi_file/1Read file + parse ABI JSON
parse_abi_file!/1Same, raises on error
parse_sol/1Parse Solidity source string → enriched map
parse_sol!/1Same, raises on error
resolve_sol_file/2Resolve a root .sol file, its imports, and remappings
resolve_sol_file!/2Same, raises on error
parse_sol_file/2Resolve imports/remappings, then parse the root contract
parse_sol_file!/2Same, raises on error

API Functions

FunctionArityDescriptionParam Kinds
parse_sol_file!2Resolve a Solidity file graph and parse it. Raises on error.path: value, opts: value
parse_sol_file2Resolve a Solidity file graph and parse the selected root contract.path: value, opts: value
resolve_sol_file!2Resolve a root Solidity file. Raises on error.path: value, opts: value
resolve_sol_file2Resolve a root Solidity file, its imports, and remappings.path: value, opts: value
parse_sol!1Parse a Solidity source string. Raises on error.source: value
parse_sol1Parse a Solidity source string into structured Elixir data with structs, enums, and NatSpec.source: value
parse_abi_file!1Read a file and parse its contents as Solidity ABI JSON. Raises on error.path: value
parse_abi_file1Read a file and parse its contents as Solidity ABI JSON.path: value
parse_abi_json!1Parse a Solidity ABI JSON string. Raises on error.json: value
parse_abi_json1Parse a Solidity ABI JSON string into structured Elixir data.json: value

Summary

Types

Constant definition from Solidity source.

Parsed ABI constructor entry, or nil if not present.

Enum definition from Solidity source.

Parsed ABI error entry.

Parsed ABI event entry.

Event parameter — like param() but includes :indexed flag.

Parsed ABI function entry.

Parsed function entry with NatSpec (from .sol source).

NatSpec documentation for a function.

ABI parameter with Solidity type and optional nested components.

Options for resolved Solidity file parsing.

Complete parsed ABI with functions, events, errors, and constructor.

Complete parsed Solidity source with structs, enums, constants, and NatSpec.

Foundry-style remapping string such as "@aave/core-v3/=lib/aave-v3-core/".

Resolved Solidity file graph and merged source.

Struct definition from Solidity source.

Functions

Read a file and parse its contents as Solidity ABI JSON.

Read a file and parse its contents as Solidity ABI JSON. Raises on error.

Parse a Solidity ABI JSON string into structured Elixir data.

Parse a Solidity ABI JSON string. Raises on error.

Parse a Solidity source string into structured Elixir data with structs, enums, and NatSpec.

Parse a Solidity source string. Raises on error.

Resolve a Solidity file graph and parse the selected root contract.

Resolve a Solidity file graph and parse it. Raises on error.

Resolve a root Solidity file, its imports, and remappings.

Resolve a root Solidity file. Raises on error.

Types

constant_info()

@type constant_info() :: %{name: String.t(), ty: String.t(), value: String.t()}

Constant definition from Solidity source.

constructor_info()

@type constructor_info() :: %{inputs: [param()], state_mutability: String.t()} | nil

Parsed ABI constructor entry, or nil if not present.

enum_info()

@type enum_info() :: %{name: String.t(), variants: [String.t()]}

Enum definition from Solidity source.

error_info()

@type error_info() :: %{
  name: String.t(),
  signature: String.t(),
  selector: String.t(),
  inputs: [param()]
}

Parsed ABI error entry.

event_info()

@type event_info() :: %{
  name: String.t(),
  signature: String.t(),
  topic: String.t(),
  anonymous: boolean(),
  inputs: [event_param()]
}

Parsed ABI event entry.

event_param()

@type event_param() :: %{
  name: String.t(),
  ty: String.t(),
  indexed: boolean(),
  components: [param()]
}

Event parameter — like param() but includes :indexed flag.

function_info()

@type function_info() :: %{
  name: String.t(),
  signature: String.t(),
  selector: String.t(),
  return_type: String.t(),
  state_mutability: String.t(),
  inputs: [param()],
  outputs: [param()]
}

Parsed ABI function entry.

function_info_with_natspec()

@type function_info_with_natspec() :: %{
  name: String.t(),
  signature: String.t(),
  selector: String.t(),
  return_type: String.t(),
  state_mutability: String.t(),
  inputs: [param()],
  outputs: [param()],
  natspec: natspec() | nil
}

Parsed function entry with NatSpec (from .sol source).

natspec()

@type natspec() :: %{
  notice: String.t(),
  params: %{required(String.t()) => String.t()},
  returns: %{required(String.t()) => String.t()}
}

NatSpec documentation for a function.

param()

@type param() :: %{name: String.t(), ty: String.t(), components: [param()]}

ABI parameter with Solidity type and optional nested components.

parse_sol_file_opts()

@type parse_sol_file_opts() :: [
  remappings: [remapping_string()],
  root_contract: String.t()
]

Options for resolved Solidity file parsing.

parsed_abi()

@type parsed_abi() :: %{
  functions: [function_info()],
  events: [event_info()],
  errors: [error_info()],
  constructor: constructor_info()
}

Complete parsed ABI with functions, events, errors, and constructor.

parsed_sol()

@type parsed_sol() :: %{
  functions: [function_info_with_natspec()],
  events: [event_info()],
  errors: [error_info()],
  constructor: constructor_info(),
  structs: [struct_info()],
  enums: [enum_info()],
  constants: [constant_info()]
}

Complete parsed Solidity source with structs, enums, constants, and NatSpec.

remapping_string()

@type remapping_string() :: String.t()

Foundry-style remapping string such as "@aave/core-v3/=lib/aave-v3-core/".

resolved_sol_file()

@type resolved_sol_file() :: %{
  source: String.t(),
  files: [String.t()],
  root_contract: String.t()
}

Resolved Solidity file graph and merged source.

struct_info()

@type struct_info() :: %{
  name: String.t(),
  fields: [%{name: String.t(), ty: String.t()}]
}

Struct definition from Solidity source.

Functions

parse_abi_file(path)

@spec parse_abi_file(String.t()) ::
  {:ok, parsed_abi()}
  | {:error, {:parse_error, String.t()} | {:file_error, String.t()}}

Read a file and parse its contents as Solidity ABI JSON.

Parameters

  • path - Path to an ABI JSON file (e.g. "priv/abis/erc20.json") (value)

Returns

Parsed ABI with :functions, :events, :errors, :constructor keys ({:ok, parsed_abi()} | {:error, {:parse_error, String.t()} | {:file_error, String.t()}})

# descripex:contract
%{
  params: %{
    path: %{
      description: "Path to an ABI JSON file (e.g. \"priv/abis/erc20.json\")",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, parsed_abi()} | {:error, {:parse_error, String.t()} | {:file_error, String.t()}}",
    description: "Parsed ABI with :functions, :events, :errors, :constructor keys"
  }
}

parse_abi_file!(path)

@spec parse_abi_file!(String.t()) :: parsed_abi()

Read a file and parse its contents as Solidity ABI JSON. Raises on error.

Parameters

  • path - Path to an ABI JSON file (e.g. "priv/abis/erc20.json") (value)

Returns

Parsed ABI with :functions, :events, :errors, :constructor keys (parsed_abi())

# descripex:contract
%{
  params: %{
    path: %{
      description: "Path to an ABI JSON file (e.g. \"priv/abis/erc20.json\")",
      kind: :value
    }
  },
  returns: %{
    type: "parsed_abi()",
    description: "Parsed ABI with :functions, :events, :errors, :constructor keys"
  }
}

parse_abi_json(json)

@spec parse_abi_json(String.t()) ::
  {:ok, parsed_abi()} | {:error, {:parse_error, String.t()}}

Parse a Solidity ABI JSON string into structured Elixir data.

Parameters

  • json - ABI JSON string (standard solc output format — array of ABI items) (value)

Returns

Parsed ABI with :functions, :events, :errors, :constructor keys ({:ok, parsed_abi()} | {:error, {:parse_error, String.t()}})

# descripex:contract
%{
  params: %{
    json: %{
      description: "ABI JSON string (standard solc output format — array of ABI items)",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, parsed_abi()} | {:error, {:parse_error, String.t()}}",
    description: "Parsed ABI with :functions, :events, :errors, :constructor keys"
  }
}

parse_abi_json!(json)

@spec parse_abi_json!(String.t()) :: parsed_abi()

Parse a Solidity ABI JSON string. Raises on error.

Parameters

  • json - ABI JSON string (standard solc output format — array of ABI items) (value)

Returns

Parsed ABI with :functions, :events, :errors, :constructor keys (parsed_abi())

# descripex:contract
%{
  params: %{
    json: %{
      description: "ABI JSON string (standard solc output format — array of ABI items)",
      kind: :value
    }
  },
  returns: %{
    type: "parsed_abi()",
    description: "Parsed ABI with :functions, :events, :errors, :constructor keys"
  }
}

parse_sol(source)

@spec parse_sol(String.t()) ::
  {:ok, parsed_sol()} | {:error, {:parse_error, String.t()}}

Parse a Solidity source string into structured Elixir data with structs, enums, and NatSpec.

Parameters

  • source - Solidity source code string (e.g. an interface definition) (value)

Returns

Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys ({:ok, parsed_sol()} | {:error, {:parse_error, String.t()}})

# descripex:contract
%{
  params: %{
    source: %{
      description: "Solidity source code string (e.g. an interface definition)",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, parsed_sol()} | {:error, {:parse_error, String.t()}}",
    description: "Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys"
  }
}

parse_sol!(source)

@spec parse_sol!(String.t()) :: parsed_sol()

Parse a Solidity source string. Raises on error.

Parameters

  • source - Solidity source code string (e.g. an interface definition) (value)

Returns

Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys (parsed_sol())

# descripex:contract
%{
  params: %{
    source: %{
      description: "Solidity source code string (e.g. an interface definition)",
      kind: :value
    }
  },
  returns: %{
    type: "parsed_sol()",
    description: "Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys"
  }
}

parse_sol_file(path, opts \\ [])

@spec parse_sol_file(String.t(), parse_sol_file_opts()) ::
  {:ok, parsed_sol()}
  | {:error, {:parse_error, String.t()} | {:file_error, String.t()}}

Resolve a Solidity file graph and parse the selected root contract.

Parameters

  • path - Path to a root .sol file (e.g. "priv/contracts/IPool.sol") (value)
  • opts - Keyword opts. Supports :root_contract override and :remappings with Foundry-style prefix=target entries (value)

Returns

Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys ({:ok, parsed_sol()} | {:error, {:parse_error, String.t()} | {:file_error, String.t()}})

# descripex:contract
%{
  params: %{
    path: %{
      description: "Path to a root .sol file (e.g. \"priv/contracts/IPool.sol\")",
      kind: :value
    },
    opts: %{
      description: "Keyword opts. Supports :root_contract override and :remappings with Foundry-style `prefix=target` entries",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, parsed_sol()} | {:error, {:parse_error, String.t()} | {:file_error, String.t()}}",
    description: "Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys"
  }
}

parse_sol_file!(path, opts \\ [])

@spec parse_sol_file!(String.t(), parse_sol_file_opts()) :: parsed_sol()

Resolve a Solidity file graph and parse it. Raises on error.

Parameters

  • path - Path to a root .sol file (e.g. "priv/contracts/IPool.sol") (value)
  • opts - Keyword opts. Supports :root_contract override and :remappings with Foundry-style prefix=target entries (value)

Returns

Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys (parsed_sol())

# descripex:contract
%{
  params: %{
    path: %{
      description: "Path to a root .sol file (e.g. \"priv/contracts/IPool.sol\")",
      kind: :value
    },
    opts: %{
      description: "Keyword opts. Supports :root_contract override and :remappings with Foundry-style `prefix=target` entries",
      kind: :value
    }
  },
  returns: %{
    type: "parsed_sol()",
    description: "Enriched parsed data with :functions, :events, :errors, :constructor, :structs, :enums, :constants keys"
  }
}

resolve_sol_file(path, opts \\ [])

@spec resolve_sol_file(String.t(), parse_sol_file_opts()) ::
  {:ok, resolved_sol_file()}
  | {:error, {:file_error, String.t()} | {:parse_error, String.t()}}

Resolve a root Solidity file, its imports, and remappings.

Parameters

  • path - Path to the root .sol file (value)
  • opts - Keyword opts. Supports :root_contract override and :remappings with Foundry-style prefix=target entries (value)

Returns

Merged source, resolved file list, and selected root contract ({:ok, resolved_sol_file()} | {:error, {:file_error, String.t()} | {:parse_error, String.t()}})

# descripex:contract
%{
  params: %{
    path: %{description: "Path to the root .sol file", kind: :value},
    opts: %{
      description: "Keyword opts. Supports :root_contract override and :remappings with Foundry-style `prefix=target` entries",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, resolved_sol_file()} | {:error, {:file_error, String.t()} | {:parse_error, String.t()}}",
    description: "Merged source, resolved file list, and selected root contract"
  }
}

resolve_sol_file!(path, opts \\ [])

@spec resolve_sol_file!(String.t(), parse_sol_file_opts()) :: resolved_sol_file()

Resolve a root Solidity file. Raises on error.

Parameters

  • path - Path to the root .sol file (value)
  • opts - Keyword opts. Supports :root_contract override and :remappings with Foundry-style prefix=target entries (value)

Returns

Merged source, resolved file list, and selected root contract (resolved_sol_file())

# descripex:contract
%{
  params: %{
    path: %{description: "Path to the root .sol file", kind: :value},
    opts: %{
      description: "Keyword opts. Supports :root_contract override and :remappings with Foundry-style `prefix=target` entries",
      kind: :value
    }
  },
  returns: %{
    type: "resolved_sol_file()",
    description: "Merged source, resolved file list, and selected root contract"
  }
}