Axiom Query Protocol
How Axiom trustlessly fulfill queries into on-chain data.
The AxiomV1Query
contract allows users to query arbitrary block header, account, and storage data from the history of Ethereum. Queries can be submitted on-chain, and query results are verified on-chain with zero-knowledge proofs of validity. We explain how this works below.
Initiating queries
Anyone can initiate a query into Axiom with either on- or off-chain data availability using the following functions in AxiomV1Query
:
sendQuery
-- Request a proof forkeccakQueryResponse
. This allows the caller to specify arefundee
and also provide on-chain data availability for the query inquery.
sendOffchainQuery
-- Request a proof forkeccakQueryResponse
. This allows the caller to specify arefundee
and also provide off-chain data availability for the query inipfsHash
.
Each query request must be accompanied by an on-chain payment which is collected upon fulfillment. The minimum payment allowed is specified by minQueryPrice
in AxiomV1Query
and is initially set to 0.01 ETH. If a query is not fulfilled by a pre-specified deadline, anyone can process a refund to the pre-specified refundee
:
collectRefund
allows anyone to process a refund for a query specified bykeccakQueryResponse
.
Fulfilling queries
Queries are fulfilled by submitting a proof that verifies keccakQueryResponse
against the cache of block hashes in AxiomV1
. We have permissioned fulfillment to the PROVER_ROLE
for safety at the moment.
fulfillQueryVsMMR
allows a prover to supply a proof which proveskeccakQueryResponse
was correct against the Merkle Mountain range stored in indexmmrIdx
ofAxiomV1.mmrRingBuffer
. The prover must also pass some additional witness data inmmrWitness
and the ZK proof itself inproof
. The prover can collect payment topayee
.verifyResultVsMMR
allows a prover to prove akeccakQueryResponse
without on-chain query request.
Both of these fulfillment functions use the verifier deployed at mmrVerifierAddress
to verify a ZK proof of the query result. This proof has public inputs/outputs given by the following, where mmr
is a variable length array of bytes32 containing the Merkle Mountain Range that proof
is proving into, and mmr[idx]
is either bytes32(0)
or the Merkle root of 1 << idx
block hashes.
poseidonBlockResponse
as a field elementkeccakBlockResponse
as 2 field elements, in hi-lo formposeidonAccountResponse
as a field elementkeccakAccountResponse
as 2 field elements, in hi-lo formposeidonStorageResponse
as a field elementkeccakStorageResponse
as 2 field elements, in hi-lo formhistoricalMMRKeccak
which iskeccak256(abi.encodePacked(mmr[10:]))
as 2 field elements in hi-lo form.recentMMRKeccak
which iskeccak256(abi.encodePacked(mmr[:10]))
as 2 field elements in hi-lo form.
Here, hi-lo form means a uint256 (a << 128) + b
is represented as two uint256's a
and b
, each of which is guaranteed to contain a uint128. The proof checks that
The
{poseidon, keccak}{Block, Account, Storage}Response
are consistent relative to the Merkle Mountain range of block hashes committed to inhistoricalMMRKeccak
andrecentMMRKeccak
.
In ZK Circuits for Axiom Queries, we explain how our ZK circuits check this claim.
Upon verification, the smart contract uses the additional witness data in mmrWitness
to check historicalMMRKeccak
and recentMMRKeccak
are consistent with the on-chain cache of block hashes in AxiomV1
by checking:
historicalMMRKeccak
appears in indexmmrIndex
ofAxiomV1.mmrRingBuffer
.recentMMRKeccak
is either committed to by an element ofAxiomV1.historicalRoots
or is an extension of such an element by block hashes accessible to the EVM.
If all checks pass, the fulfilled results keccakQueryResponse
and poseidonQueryResponse
are stored in verifiedKeccakResults
and verifiedPoseidonResults
.
Reading verified query results
We support reading block, account, and storage data from verified query results via:
areResponsesValid
-- Check whether queries into block, account, and storage data have been verified. Each query is specified by:BlockResponse
-- TheblockNumber
andblockHash
as well as a Merkle proofproof
and leaf locationleafIdx
inkeccakBlockResponse
.AccountResponse
-- TheblockNumber
,addr
,nonce
,balance
,storageRoot
, andcodeHash
as well as a Merkle proofproof
and leaf locationleafIdx
inkeccakAccountResponse
.StorageResponse
-- TheblockNumber
,addr
,slot
, andvalue
as well as a Merkle proofproof
and leaf locationleafIdx
inkeccakStorageResponse
.
The raw query results may also be accessed using:
isKeccakResultValid
-- Check whether a query consisting ofkeccakBlockResponse
,keccakAccountResponse
, andkeccakStorageResponse
has already been verified.isPoseidonResultValid
-- Check whether a query consisting ofposeidonBlockResponse
,poseidonAccountResponse
, andposeidonStorageResponse
has already been verified.
Last updated