Onchain.Sleuth (onchain v0.5.4)

Copy Markdown View Source

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:

SourceShape
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

FunctionPurpose
query/5Execute deploy-as-call → decoded values list
query!/5Same, raises on error

API Functions

FunctionArityDescriptionParam Kinds
query!5Execute a Sleuth deploy-as-call. Raises on error.bytecode: value, constructor_types: value, constructor_args: value, return_type: value, opts: value
query5Execute 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

query(bytecode, constructor_types, constructor_args, return_type, opts \\ [])

@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 of solc --bin or OnchainJs.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"
  }
}

query!(bytecode, constructor_types, constructor_args, return_type, opts \\ [])

@spec query!(String.t(), String.t(), tuple(), String.t(), keyword()) :: list()

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"}
}