# Axiom Query Protocol

The Axiom V2 Query protocol consists of the following smart contracts:

* `AxiomV2Query`: the primary smart contract for accepting and fulfilling user queries.
* `AxiomV2Prover`: smart contract to manage permissions around who can submit ZK proofs to fulfill queries.
* `AxiomV2HeaderVerifier`: smart contract for verifying the block hashes used in ZK proofs are valid against the block hash cache [maintained](/axiomv2-sdk/protocol-design/caching-block-hashes.md) by `AxiomV2Core`.
* `AxiomResultStore`: smart contract that stores the results of queries into `AxiomV2Query`.

## `AxiomV2Query`

`AxiomV2Query` uses `AxiomV2Core` to fulfill queries made by users into Axiom V2. `AxiomV2Query` follows the [Axiom V2 Query Format](/axiomv2-sdk/protocol-design/axiom-query-protocol/axiom-query-format.md) and supports:

* On-chain query requests with on- or off\*-chain data availability for queries and on-chain payments or refunds. (\*Off-chain data availability not yet supported in the testnet release.)
* On-chain fulfillment of queries with on-chain proof verification.

For full details of the Axiom V2 Query format, see the following page:

{% content-ref url="/pages/SIMYAt0MgfQLTb72b2R9" %}
[Axiom Query Format](/axiomv2-sdk/protocol-design/axiom-query-protocol/axiom-query-format.md)
{% endcontent-ref %}

### **Initiating queries on-chain**

Users can initiate a query on-chain with on-chain payment. Both on- and off-chain data availability are supported for the data query:

* `sendQuery`: Send an on-chain query with on-chain data availability.
* `sendQueryWithIpfsData`: Send an on-chain query with data availability on IPFS.
  * This is not yet supported in the testnet release.

On-chain queries are identified by `queryId` as specified in the [Axiom V2 Query Format](/axiomv2-sdk/protocol-design/axiom-query-protocol/axiom-query-format.md). For each query, `AxiomQueryMetadata` in `queries[queryId]` stores the relevant metadata, consisting of:

* `state` (`AxiomQueryState`): One of `Inactive`, `Active`, `Fulfilled`, or `Paid`.
* `deadlineBlockNumber` (`uint32`): The block number after which the query is eligible for a refund.
* `payee` (`address`): Once fulfilled, the address payment is due to.
* `payment` (`uint256`): The payment amount, in gwei, escrowed for this query.

### **Query fulfillment**

Query fulfillment is permissioned to the `PROVER_ROLE`, which is initialized to an [`AxiomV2Prover`](#axiomv2prover) contract to manage proving permissions for safety at the moment. There are two ways the `PROVER_ROLE` can fulfill queries:

* `fulfillQuery`: Fulfill an existing on-chain query.
* `fulfillOffchainQuery`: Fulfill a query which was initiated off-chain.

These functions take in a ZK proof verifying a query and fulfill the query by:

* verifying the ZK proof on-chain
* checking the block hashes used in the ZK proof (in the form of a Merkle mountain range) are validated against the cache in [`AxiomV2Core`](/axiomv2-sdk/protocol-design/caching-block-hashes.md) using [`AxiomV2HeaderVerifier`](#axiomv2headerverifier)
* for on-chain queries: checking that the query that was just verified corresponds to query originally requested on-chain, by matching the `queryHash`
* calling the desired callback

### **Fees and permissions**

All fees are charged in ETH. User balances are maintained in the `balances` mapping.

* To deposit, users can use `deposit` or transfer ETH together with their on-chain query.
* To withdraw, users can use `withdraw`.

The fee for each query is determined by:

* `maxFeePerGas` (`uint64`): The max fee to use in the fulfillment transaction.
* `callbackGasLimit` (`uint32`): Gas limit allocated for use in the callback.

Each on-chain query will escrow a max payment of

```
maxQueryPri = maxFeePerGas * (callbackGasLimit + proofVerificationGas) + axiomQueryFee;
```

where

* `proofVerificationGas`: Gas cost of proof verification, currently set to `500_000`
* `axiomQueryFee`: Fee charged by Axiom, fixed to `0.003 ether`

To increase gas parameters after making a query, anyone can add funds to a query with `increaseQueryGas`.

Upon fulfillment, the `maxQueryPri` fee is released to the prover, who can call `unescrow` to claim payment.

* The prover can refund the portion of `maxQueryPri` not used in gas or the `axiomQueryFee` to the original query `caller`.
* If the query is not fulfilled by `deadlineBlockNumber`, the `caller` can retrieve their fees paid using `refundQuery`

## `AxiomV2Prover`

`AxiomV2Prover` manages permissions for `fulfillQuery` and `fulfillOffchainQuery` calls into `AxiomV2Query`. These calls are restricted to:

* accounts holding the `PROVER_ROLE`, initially anticipated to be controlled by the Axiom team
  * The `PROVER_ROLE` is currently limited to guard against exploits of the Axiom ZK circuits.  In the event that a ZK circuit is found to be under-constrained, this prevents exploits by malicious provers who could use this to prove inaccurate results to Axiom queries. As the ZK circuit codebase matures, we intend to remove this permissioning.
* additional accounts permissioned for each `(querySchema, target)` pair, tracked in the `allowedProvers` mapping

All calls to `AxiomV2Prover` are forwarded to `AxiomV2Query`.

## `AxiomV2HeaderVerifier`

`AxiomV2HeaderVerifier` verifies that a Merkle mountain range `proofMmr` of block hashes is committed to by block hashes available to [`AxiomV2Core`](/axiomv2-sdk/protocol-design/caching-block-hashes.md) in `verifyQueryHeaders`. This happens by comparing `proofMmr` to:

* the padded Merkle mountain ranges committed to in `pmmrSnapshots` and `blockhashPmmr`
* the block hashes available in the EVM via the [`BLOCKHASH`](https://www.evm.codes/#40?fork=shanghai) opcode

## `AxiomResultStore`

`AxiomResultStore` stores results from queries into Axiom V2, indexed by `queryHash`. We store these in the mapping `results`, where `results[queryHash]` stores

```solidity
resultHash = keccak(sourceChainId . dataResultsRoot . dataResultsPoseidonRoot . computeResultsHash)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://intrinsic-1.gitbook.io/axiomv2-sdk/protocol-design/axiom-query-protocol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
