Axiom V2 Docs Old
  • Introduction
    • What is Axiom?
    • Quickstart
  • Examples
    • Autonomous Airdrop
      • AxiomREPL Code
      • Contract
      • Web App
      • DataQuery-only Version
  • Developers
    • Axiom for Developers
    • Specifying a Query into Axiom
    • AxiomREPL
      • AxiomREPL Examples
    • Exporting a Client Side Prover
    • Handling Axiom Callbacks
    • Common Issues
      • Callback Debugging
  • SDK and REPL Reference
    • Axiom SDK Reference
      • QueryBuilderV2
      • Data Subqueries
        • Header Subquery
        • Account Subquery
        • Storage Subquery
        • Transaction Subquery
        • Receipt Subquery
        • Solidity Nested Mapping Subquery
    • AxiomREPL Reference
      • Circuit Types
      • Circuit Functions
      • Data Functions
      • Compute Functions
  • Protocol Design
    • Architecture Overview
    • Caching Block Hashes
    • Axiom Query Protocol
      • Axiom Query Format
    • ZK Circuits for Axiom Queries
    • Ethereum On-chain Data
    • Guardrails
  • Transparency and Security
    • KZG Trusted Setup
    • Contract Addresses
    • On-chain ZK Verifiers
    • Security
  • Zero Knowledge Proofs
    • Introduction to ZK
    • ZK Examples
    • Getting Started with halo2
    • halo2-repl
  • Additional Resources
    • Axiom V2 Explorer
    • Github
    • Website
    • Telegram
    • Discord
    • Axiom V1 Docs
Powered by GitBook
On this page
  • Specifying a callback in the Axiom SDK
  • Receiving the Callback
  • Parsing the Callback
  • Examples
  1. Developers

Handling Axiom Callbacks

Using Axiom-verified results in your contract

Callbacks are triggered automatically once your Query is fulfilled by the Axiom V2 prover. The proof will be verified via Axiom's on-chain verifier before the callback to your smart contract is called.

Specifying a callback in the Axiom SDK

The AxiomV2Callback struct can be built with the following fields:

  • target: the address of the contract to call the callback on

  • extraData: data that's passed to the callback (the EVM will automatically right-pad zeroes to this field for any size, which is probably not what you want, so it's recommended that you convert this to bytes32 if you are dealing with types that are not a multiple of 32 bytes)

const exampleClientAddr = "0x888d44c887DFCfaeBBf41C53eD87C0C9ED994165";
const callback: AxiomV2Callback = {
    target: exampleClientAddr,
    extraData: bytes32(0),
}

And subsequently set for the Query:

query.setCallback(callback);

The callback's resultLen will be automatically updated based on the dataQuery or computeQuery set on the Query.

Receiving the Callback

In order to properly receive the Axiom V2 callback in your contract, you'll need to create a function that has the following argument format:

function axiomV2Callback(
    uint64 sourceChainId,
    address caller,
    bytes32 querySchema,
    uint256 queryId,
    bytes32[] calldata axiomResults,
    bytes calldata extraData
) external { 
    // validate msg.sender against the AxiomV2Query address
    <...>
    
    // validate the sourceChainId, caller, querySchema, and queryId
    <...>
    
    // perform your application logic
    <...>
}
  • sourceChainId: The numerical ID of the chain that the Query was generated from

  • caller: The original contract or EOA that sent the query to Axiom V2

  • querySchema: The hashed schema, defined as keccak256(k . vkeyLen . vkey) and is essentially a commitment to the circuit defined in the computeQuery

  • queryId: A unique identifier for the submitted Query

  • axiomResults: An array of the results in bytes32 format

    • If you used a ComputeQuery, your results will be returned in the order and number of times in which you called addToCallback(value)

    • If you used a DataQuery, your results will be returned as value of the results of your data subqueries in the order that you appended them to the Query

Parsing the Callback

When you receive the callback, you will want to validate that all of the fields match so that no one who maliciously submits a Query with invalid data is able to pass the validation.

Additionally, you will want to parse the axiomResults array to ensure that the data that is passed in matches all of the conditions that are required for the user. For example, if you require that a user submits a proof that their account balance is above 1 ETH at some historic block, you'll likely want to validate that the value of the index of the axiomResults array of the account balance is greater than 1 ETH.

Examples

PreviousExporting a Client Side ProverNextCommon Issues

Last updated 1 year ago

We have an .

Additionally, the also contains an example implementation.

example client implementation here
Autonomous Airdrop example