Comment on page
Let users autonomously qualify themselves for airdrops based on contract-specified criteria.
This Autonomous Airdrop example checks if a user has used Uniswap on Goerli (swapping a token for a token that is not ETH) on or after block 9000000, and if so, sends 100 UselessToken to the user. UselessToken is a test token and has no monetary value.
WARNING: This code is not audited and is only provided as an example.
Flow diagram for the full Autonomous Airdrop system
For the airdrop parameters that we've specified, we'd like to figure out exactly how we can get this data from the blockchain. First, we'll dive a little deeper into how event logs work.
When a Solidity contract
emits an event, that event is saved in the transaction receipt's
logsarray. This array contains every event that was emitted during that transaction. Each
logrecords up to 3
topics and some amount of data.
topics are marked as
indexedin the event and are easily searchable, whereas data is any field without
indexedand is not as easily searchable. Here's an example
Swapevent at this transaction here that we're interested in for our airdrop parameters.
We're looking at one example transaction right now, but the guidelines we'll build will be universal for all transactions. In order to show that a user has performed a Swap on the
UniswapUniversalRouteron or after block 9000000, we want to use the following four pieces of data:
event schemafor the event (see note below for details), which always lives on topic index 0 of the event, matches the
recipientfield of the
Swapevent matches the user's address
blockNumberis >= 9000000
UniswapUniversalRouter's contract address
The event schema is always topic
0in an event log on Etherscan.
Note: you can use this online keccak256 tool to validate that the Swap event schema
0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67is indeed equal to the keccak256 hash (with
0xprepended) of the function signature:
We utilize Alchemy's Transaction JSON-RPC to grab all transactions from the user that fit the criteria that it was sent from the user's address to the UniswapUniversalRouter's address. For each transaction, we get the receipt as well and then we parse through that data according to the 4 parameters outlined above to find an appropriate Event that matches.
This example contains 3 parts: the client circuit, client contract, and webapp. Client Circuit is the special ZK circuit written to generate specific Axiom queries from your web app. Client Contract contains all of the Solidity contract code to implement preprocessing the transaction data. Web App contains the code for a Next.js 13 (app router) web app.
Last modified 11d ago