Compound-style "deploy-as-call" primitive for arbitrary read-only logic against live chain state.
Sends an eth_call with no to and creation bytecode as data. The node
executes the constructor in-memory against live state; the response is
the bytes the constructor would have deployed. The caller ABI-decodes
those bytes as the query result.
Complements Onchain.Multicall (batches existing view functions) and
onchain_evm / revm (local simulation). Use Sleuth when you need
derived or conditional logic that isn't exposed as a view function and
you want live-state execution in one RPC round-trip.
Inspired by Compound's Sleuth: https://github.com/compound-finance/sleuth
Bytecode must be supplied by the caller. Solidity source → bytecode
compilation is out of scope — use OnchainJs.Solc.compile/2
(onchain_js Task 2) or an external build step (foundry, hardhat).
Error Format
Pass-through from underlying modules:
| Source | Shape |
|---|---|
Onchain.Hex.decode/1 on bytecode | {:error, {:invalid_hex, _}} |
Onchain.ABI.encode_call/2 on ctor args | {:error, {:encode_error, _}} |
Onchain.RPC.call/3 | {:error, {:rpc_error, _}} |
Onchain.ABI.decode_response/2 | {:error, {:decode_error, _}} |
Functions
| Function | Purpose |
|---|---|
query/5 | Execute deploy-as-call → decoded values list |
query!/5 | Same, raises on error |
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
query! | 5 | Execute a Sleuth deploy-as-call. Raises on error. | bytecode: value, constructor_types: value, constructor_args: value, return_type: value, opts: value |
query | 5 | Execute a Sleuth deploy-as-call: encode ctor args, append to bytecode, eth_call, decode. | bytecode: value, constructor_types: value, constructor_args: value, return_type: value, opts: value |
Summary
Functions
Execute a Sleuth deploy-as-call: encode ctor args, append to bytecode, eth_call, decode.
Execute a Sleuth deploy-as-call. Raises on error.
Functions
@spec query(String.t(), String.t(), tuple(), String.t(), keyword()) :: {:ok, list()} | {:error, term()}
Execute a Sleuth deploy-as-call: encode ctor args, append to bytecode, eth_call, decode.
Parameters
bytecode- Creation bytecode as 0x-prefixed hex string (output ofsolc --binorOnchainJs.Solc.compile/2) (value)constructor_types- Tuple type signature for constructor args, e.g. "(uint256,address)" or "()" for none (value)constructor_args- Tuple of constructor argument values matching constructor_types, e.g. {42, addr_bin} or {} (value)return_type- Tuple type signature for decoding the returned bytes, e.g. "(uint256)" or "(uint256[])" (value)opts- Options: :rpc_url, :timeout, :block (integer, "latest", "finalized", ...) (default:[], value)
Returns
List of decoded return values from the constructor's returned bytes ({:ok, [decoded]} | {:error, term()})
# descripex:contract
%{
params: %{
opts: %{
default: [],
description: "Options: :rpc_url, :timeout, :block (integer, \"latest\", \"finalized\", ...)",
kind: :value
},
return_type: %{
description: "Tuple type signature for decoding the returned bytes, e.g. \"(uint256)\" or \"(uint256[])\"",
kind: :value
},
bytecode: %{
description: "Creation bytecode as 0x-prefixed hex string (output of `solc --bin` or `OnchainJs.Solc.compile/2`)",
kind: :value
},
constructor_types: %{
description: "Tuple type signature for constructor args, e.g. \"(uint256,address)\" or \"()\" for none",
kind: :value
},
constructor_args: %{
description: "Tuple of constructor argument values matching constructor_types, e.g. {42, addr_bin} or {}",
kind: :value
}
},
returns: %{
type: "{:ok, [decoded]} | {:error, term()}",
description: "List of decoded return values from the constructor's returned bytes"
}
}
Execute a Sleuth deploy-as-call. Raises on error.
Parameters
bytecode- Creation bytecode as 0x-prefixed hex (value)constructor_types- Tuple type signature, e.g. "(uint256,address)" or "()" (value)constructor_args- Tuple of ctor values, e.g. {42, addr_bin} or {} (value)return_type- Return tuple type, e.g. "(uint256[])" (value)opts- Options: :rpc_url, :timeout, :block (default:[], value)
Returns
List of decoded return values ([decoded])
# descripex:contract
%{
params: %{
opts: %{
default: [],
description: "Options: :rpc_url, :timeout, :block",
kind: :value
},
return_type: %{
description: "Return tuple type, e.g. \"(uint256[])\"",
kind: :value
},
bytecode: %{
description: "Creation bytecode as 0x-prefixed hex",
kind: :value
},
constructor_types: %{
description: "Tuple type signature, e.g. \"(uint256,address)\" or \"()\"",
kind: :value
},
constructor_args: %{
description: "Tuple of ctor values, e.g. {42, addr_bin} or {}",
kind: :value
}
},
returns: %{type: "[decoded]", description: "List of decoded return values"}
}