ABI encoding/decoding for Ethereum contract calls.
Wraps the hieroglyph ABI library (transitively pulled in by cartouche) with 0x-prefixed hex string
handling and consistent error tuples. Consumers work with hex strings from
RPC; this module bridges the gap.
Type Signatures
decode_response/2 (and its alias decode_types/2) expects tuple type
syntax for return values — the type list MUST be wrapped in parentheses,
e.g. "(uint256)" or "(uint256,bool)". Bare comma-separated types
("uint256,bool") raise an unhelpful upstream error and are not accepted.
This is the standard pattern for decoding eth_call responses — NOT
function signatures with names.
Use decode_response/2 when the input is an eth_call reply; use
decode_types/2 when the input is arbitrary ABI-encoded bytes
(mempool calldata, custom payloads). They behave identically.
Error Format
- Encode errors:
{:error, {:encode_error, reason}} - Decode errors:
{:error, {:decode_error, reason}}
Where reason is either:
- A string from the upstream exception message
- A tuple like
{:invalid_hex, hex_data}preserving the original hex error
Functions
| Function | Purpose |
|---|---|
encode_call/2 | Function signature + params → hex calldata |
encode_call!/2 | Same, raises on error |
decode_response/2 | Type signature + hex data → decoded values |
decode_response!/2 | Same, raises on error |
decode_types/2 | Alias of decode_response/2 for non-RPC callers |
decode_types!/2 | Alias of decode_response!/2, raises on error |
decode_call/3 | Selector-prefixed calldata → decoded function args (forwards opts) |
decode_call!/3 | Same, raises on error |
decode_error/2 | Solidity 0.8.4+ custom-error revert data → %{error, args} |
decode_error!/2 | Same, raises on error |
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
decode_error! | 2 | Decode custom-error revert data. Raises on error. | hex_revert_data: value, error_definitions: value |
decode_error | 2 | Decode Solidity 0.8.4+ custom-error revert data against a list of candidate error signatures. | hex_revert_data: value, error_definitions: value |
decode_call! | 3 | Decode selector-prefixed calldata. Raises on error. | signature_or_selector: value, hex_calldata: value, opts: value |
decode_call | 3 | Decode selector-prefixed calldata to function args. | signature_or_selector: value, hex_calldata: value, opts: value |
decode_types! | 2 | Decode arbitrary ABI-encoded hex data. Alias of decode_response!/2. | type_signature: value, hex_data: value |
decode_types | 2 | Decode arbitrary ABI-encoded hex data. Alias of decode_response/2. | type_signature: value, hex_data: value |
decode_response! | 2 | Decode hex-encoded ABI response data to Elixir values. Raises on error. | type_signature: value, hex_data: value |
decode_response | 2 | Decode hex-encoded ABI response data to Elixir values. | type_signature: value, hex_data: value |
encode_call! | 2 | Encode a function call to 0x-prefixed hex calldata. Raises on error. | signature: value, params: value |
encode_call | 2 | Encode a function call to 0x-prefixed hex calldata. | signature: value, params: value |
Summary
Functions
Decode selector-prefixed calldata to function args.
Decode selector-prefixed calldata. Raises on error.
Decode Solidity 0.8.4+ custom-error revert data against a list of candidate error signatures.
Decode custom-error revert data. Raises on error.
Decode hex-encoded ABI response data to Elixir values.
Decode hex-encoded ABI response data to Elixir values. Raises on error.
Decode arbitrary ABI-encoded hex data. Alias of decode_response/2.
Decode arbitrary ABI-encoded hex data. Alias of decode_response!/2.
Encode a function call to 0x-prefixed hex calldata.
Encode a function call to 0x-prefixed hex calldata. Raises on error.
Functions
@spec decode_call(String.t() | ABI.FunctionSelector.t(), String.t(), keyword()) :: {:ok, list() | map()} | {:error, {:decode_error, term()}}
Decode selector-prefixed calldata to function args.
Parameters
signature_or_selector- Function signature like "transfer(address,uint256)" OR a hieroglyph FunctionSelector struct. The 4-byte selector of the signature must match the first 4 bytes of calldata. (value)hex_calldata- 0x-prefixed hex string of selector-prefixed ABI-encoded calldata (value)opts- Forwarded to hieroglyph'sABI.decode_call/3. Passdecode_structs: truefor a named-field map instead of a positional list. (default:[], value)
Returns
List of args (or map when decode_structs: true). Error reasons: :calldata_too_short, :selector_mismatch, :no_function_name, {:invalid_hex, _}, or upstream exception message string. ({:ok, list | map} | {:error, {:decode_error, reason}})
# descripex:contract
%{
params: %{
opts: %{
default: [],
description: "Forwarded to hieroglyph's `ABI.decode_call/3`. Pass `decode_structs: true` for a named-field map instead of a positional list.",
kind: :value
},
signature_or_selector: %{
description: "Function signature like \"transfer(address,uint256)\" OR a hieroglyph FunctionSelector struct. The 4-byte selector of the signature must match the first 4 bytes of calldata.",
kind: :value
},
hex_calldata: %{
description: "0x-prefixed hex string of selector-prefixed ABI-encoded calldata",
kind: :value
}
},
returns: %{
type: "{:ok, list | map} | {:error, {:decode_error, reason}}",
description: "List of args (or map when `decode_structs: true`). Error reasons: `:calldata_too_short`, `:selector_mismatch`, `:no_function_name`, `{:invalid_hex, _}`, or upstream exception message string."
}
}
Decode selector-prefixed calldata. Raises on error.
Parameters
signature_or_selector- Function signature string or hieroglyph FunctionSelector struct (value)hex_calldata- 0x-prefixed hex string of selector-prefixed calldata (value)opts- Forwarded to hieroglyph'sABI.decode_call/3(e.g.decode_structs: true) (default:[], value)
Returns
List of decoded args (or map when decode_structs: true) (list | map)
# descripex:contract
%{
params: %{
opts: %{
default: [],
description: "Forwarded to hieroglyph's `ABI.decode_call/3` (e.g. `decode_structs: true`)",
kind: :value
},
signature_or_selector: %{
description: "Function signature string or hieroglyph FunctionSelector struct",
kind: :value
},
hex_calldata: %{
description: "0x-prefixed hex string of selector-prefixed calldata",
kind: :value
}
},
returns: %{
type: "list | map",
description: "List of decoded args (or map when `decode_structs: true`)"
}
}
@spec decode_error(String.t(), [String.t() | ABI.FunctionSelector.t()]) :: {:ok, %{error: String.t() | nil, args: list()}} | {:error, {:decode_error, term()}}
Decode Solidity 0.8.4+ custom-error revert data against a list of candidate error signatures.
Parameters
hex_revert_data- 0x-prefixed hex string of revert data (4-byte error selector + ABI-encoded args) (value)error_definitions- List of candidate error signatures like ["InsufficientBalance(uint256,uint256)", "Unauthorized()"] (or hieroglyph FunctionSelector structs). The first one whose 4-byte selector matches the prefix ofhex_revert_datadecodes the args. (value)
Returns
Map with the matched error name (or nil) and decoded args. Error reasons: :calldata_too_short, :no_match, {:invalid_hex, _}, or upstream exception message string. ({:ok, %{error: name, args: list}} | {:error, {:decode_error, reason}})
# descripex:contract
%{
params: %{
error_definitions: %{
description: "List of candidate error signatures like [\"InsufficientBalance(uint256,uint256)\", \"Unauthorized()\"] (or hieroglyph FunctionSelector structs). The first one whose 4-byte selector matches the prefix of `hex_revert_data` decodes the args.",
kind: :value
},
hex_revert_data: %{
description: "0x-prefixed hex string of revert data (4-byte error selector + ABI-encoded args)",
kind: :value
}
},
returns: %{
type: "{:ok, %{error: name, args: list}} | {:error, {:decode_error, reason}}",
description: "Map with the matched error name (or `nil`) and decoded args. Error reasons: `:calldata_too_short`, `:no_match`, `{:invalid_hex, _}`, or upstream exception message string."
}
}
@spec decode_error!(String.t(), [String.t() | ABI.FunctionSelector.t()]) :: %{ error: String.t() | nil, args: list() }
Decode custom-error revert data. Raises on error.
Parameters
hex_revert_data- 0x-prefixed hex string of revert data (value)error_definitions- List of candidate error signatures or FunctionSelector structs (value)
Returns
Map with the matched error name and decoded args (%{error: name, args: list})
# descripex:contract
%{
params: %{
error_definitions: %{
description: "List of candidate error signatures or FunctionSelector structs",
kind: :value
},
hex_revert_data: %{
description: "0x-prefixed hex string of revert data",
kind: :value
}
},
returns: %{
type: "%{error: name, args: list}",
description: "Map with the matched error name and decoded args"
}
}
Decode hex-encoded ABI response data to Elixir values.
Parameters
type_signature- Tuple type signature wrapped in parentheses, e.g. "(uint256)" or "(uint256,bool)". Bare comma-separated types like "uint256,bool" are NOT accepted and raise an unhelpful upstream error. (value)hex_data- 0x-prefixed hex string of ABI-encoded data (value)
Returns
List of decoded values ({:ok, list} | {:error, {:decode_error, reason}})
# descripex:contract
%{
params: %{
type_signature: %{
description: "Tuple type signature wrapped in parentheses, e.g. \"(uint256)\" or \"(uint256,bool)\". Bare comma-separated types like \"uint256,bool\" are NOT accepted and raise an unhelpful upstream error.",
kind: :value
},
hex_data: %{
description: "0x-prefixed hex string of ABI-encoded data",
kind: :value
}
},
returns: %{
type: "{:ok, list} | {:error, {:decode_error, reason}}",
description: "List of decoded values"
}
}
Decode hex-encoded ABI response data to Elixir values. Raises on error.
Parameters
type_signature- Tuple type signature wrapped in parentheses, e.g. "(uint256)" or "(uint256,bool)". Bare comma-separated types are NOT accepted. (value)hex_data- 0x-prefixed hex string of ABI-encoded data (value)
Returns
List of decoded values (list)
# descripex:contract
%{
params: %{
type_signature: %{
description: "Tuple type signature wrapped in parentheses, e.g. \"(uint256)\" or \"(uint256,bool)\". Bare comma-separated types are NOT accepted.",
kind: :value
},
hex_data: %{
description: "0x-prefixed hex string of ABI-encoded data",
kind: :value
}
},
returns: %{type: :list, description: "List of decoded values"}
}
Decode arbitrary ABI-encoded hex data. Alias of decode_response/2.
Parameters
type_signature- Tuple type signature wrapped in parentheses, e.g. "(uint256)" or "(uint256,bool)". Bare comma-separated types are NOT accepted. (value)hex_data- 0x-prefixed hex string of ABI-encoded data (value)
Returns
List of decoded values. Identical to decode_response/2 — use this name when the input isn't an RPC response (mempool calldata, custom ABI payloads). ({:ok, list} | {:error, {:decode_error, reason}})
# descripex:contract
%{
params: %{
type_signature: %{
description: "Tuple type signature wrapped in parentheses, e.g. \"(uint256)\" or \"(uint256,bool)\". Bare comma-separated types are NOT accepted.",
kind: :value
},
hex_data: %{
description: "0x-prefixed hex string of ABI-encoded data",
kind: :value
}
},
returns: %{
type: "{:ok, list} | {:error, {:decode_error, reason}}",
description: "List of decoded values. Identical to decode_response/2 — use this name when the input isn't an RPC response (mempool calldata, custom ABI payloads)."
}
}
Decode arbitrary ABI-encoded hex data. Alias of decode_response!/2.
Parameters
type_signature- Tuple type signature wrapped in parentheses, e.g. "(uint256)" or "(uint256,bool)". Bare comma-separated types are NOT accepted. (value)hex_data- 0x-prefixed hex string of ABI-encoded data (value)
Returns
List of decoded values (list)
# descripex:contract
%{
params: %{
type_signature: %{
description: "Tuple type signature wrapped in parentheses, e.g. \"(uint256)\" or \"(uint256,bool)\". Bare comma-separated types are NOT accepted.",
kind: :value
},
hex_data: %{
description: "0x-prefixed hex string of ABI-encoded data",
kind: :value
}
},
returns: %{type: :list, description: "List of decoded values"}
}
Encode a function call to 0x-prefixed hex calldata.
Parameters
signature- Function signature, e.g. "balanceOf(address)" (value)params- List of parameter values matching the signature (value)
Returns
0x-prefixed hex-encoded calldata ({:ok, hex_string} | {:error, {:encode_error, reason}})
# descripex:contract
%{
params: %{
signature: %{
description: "Function signature, e.g. \"balanceOf(address)\"",
kind: :value
},
params: %{
description: "List of parameter values matching the signature",
kind: :value
}
},
returns: %{
type: "{:ok, hex_string} | {:error, {:encode_error, reason}}",
description: "0x-prefixed hex-encoded calldata",
example: "0x70a08231..."
}
}
Encode a function call to 0x-prefixed hex calldata. Raises on error.
Parameters
signature- Function signature, e.g. "balanceOf(address)" (value)params- List of parameter values matching the signature (value)
Returns
0x-prefixed hex-encoded calldata (string)
# descripex:contract
%{
params: %{
signature: %{
description: "Function signature, e.g. \"balanceOf(address)\"",
kind: :value
},
params: %{
description: "List of parameter values matching the signature",
kind: :value
}
},
returns: %{type: :string, description: "0x-prefixed hex-encoded calldata"}
}