read_contract_at

Calls a contract function at an explicit historical block and returns ABI-decoded SQL values.

Example

Needs RPC · RPC required

1
-- Chainlink ETH/USD at one block per day
2
WITH as_of(day) AS (
3
SELECT day
4
FROM generate_series('2024-01-01'::DATE, '2024-01-07'::DATE, INTERVAL 1 DAY) AS t(day)
5
)
6
SELECT
7
day,
8
format_units(
9
(read_contract_at(
10
$client,
11
'0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'::ADDRESS,
12
'[{"type":"function","name":"latestRoundData","inputs":[],"outputs":[{"name":"roundId","type":"uint80"},{"name":"answer","type":"int256"},{"name":"startedAt","type":"uint256"},{"name":"updatedAt","type":"uint256"},{"name":"answeredInRound","type":"uint80"}]}]'::JSON,
13
'latestRoundData',
14
block_at($client, day::TIMESTAMPTZ)
15
)).answer,
16
8
17
)::DOUBLE AS eth_usd
18
FROM as_of;
Notebook ready in readonly mode.

API reference

Exact signatures with descriptions, requirements, inputs, returns, and examples.

read_contract_at(CLIENT, ADDRESS, JSON, VARCHAR, BIGINT, ...args) # RPC required

Accepts a typed BIGINT block number, including a per-row block_at result. ABI and function_name must be literal or foldable. Pinned and execution CLIENT values reject the explicit selector.

Inputs

NameTypeUse
clientCLIENT

Readable EVM state represented by a live, pinned, or execution CLIENT.

requiredpositional
toADDRESS

Contract address to call.

requiredpositional
abiJSON

Literal or foldable JSON ABI used for argument encoding and return typing.

requiredpositional
function_nameVARCHAR

Constant ABI function name.

requiredpositional
block_numberBIGINT

Non-negative BIGINT block number. NULL produces NULL without issuing an RPC call.

requiredpositional
Showing fewer

Returns

Name Type
result dynamic ABI-derived scalar or STRUCT

A function with one output returns that value directly. A function with multiple outputs returns a STRUCT with fields named from ABI outputs, or output0, output1, and so on for unnamed outputs.

Guidance

Historical contract reads

Use read_contract_at when the block number is already a typed BIGINT value or comes from block_at.

The ABI and function name remain planning-time constants so the exact scalar or STRUCT return type can be inferred.

  • NULL block numbers return NULL without an RPC request.
  • Negative block numbers are rejected locally.
  • Use read_contract options instead when you need a block tag, on_error, or a dynamic return schema.

Related functions

Category and tags

Category
Chain reads
Tag
RPC