Onchain Tutorial (1/2): Code Your Airdrop Contract With Privately-Aggregated Data
Last updated
Last updated
This tutorial is designed as an introduction to Sismo Connect Solidity Library.
It shows you how to create a Sybil-resistant ERC20 airdrop from privately-aggregated data. Take a look at the to deeply understand the use case.
You will learn how to request ZK proofs about your user's data and verify them in your smart contracts.
This tutorial requires:
>= 18.15.0 (Latest LTS version)
(see how to install it )
MetaMask installed in your browser
This tutorial is based on the following . You can clone it with the following command:
You can now launch your local app with the commands:
You can now play with the local app that already integrates Sismo Connect. You should be able to claim your airdrop!
The interaction with the fork network can become quite unstable if you stop the yarn chain
command at some point or if you already used the sample app before.
You can end up with an infinitely pending transaction.
If so:
keep the local anvil node running,
make sure to delete your activity tab for the fork network in MetaMask by going to "Settings > Advanced > Clear activity tab data" when connected to the fork network.
relaunch the anvil node and the application
This tutorial does not need any anvil
or front-end restart; everything auto-reloads for you. You should only save the files you make changes to and play with your front end.
Congrats on getting your airdrop! Now, let's see how this simple Sismo Connect integration works behind the scenes and improve it along the way.
Go to the front/src/app/page.tsx
For this tutorial, we will use an already existing app (appId: 0xf4977993e52606cfd67b7a1cde717069)
Don't forget to remove impersonated accounts if you plan to deploy in production
Let's add the Sismo Connect Button and request thevaultId
of users.
What are the different React button props?
auths:
Request proof of ownership of Data Sources here (Wallet, GitHub, Telegram, Twitter and vaultId).
signature:
We can request users to sign a message; here, we request them to sign the recipient address for the airdrop, protecting them from front-running.
onResponseBytes:
a function that will be called after the user has generated the ZK proof and sent the Sismo Connect Response. Here we are just storing the response.
text:
Content on the button
Now let's see how the contracts work!
Let's verify the ZK proof in your contract. Go to src/Airdrop.sol
Below is the code that initiates the contract with the Sismo Connect Solidity Library, and like in the front end, it must be initiated with a configuration.
Take a look at the claimWithSismo
function. It takes the Sismo Connect Response as an argument (which is received by the front after the user has generated the ZK proof) and verifies the response as valid against the authentication and the signature requested.
If the response is valid, it checks that the airdrop has not been claimed before by the associatedvaultId
and finally mints 100 tokens to the address in the signature.
The vaultId
enables protection against double spends in an anonymous way. Indeed, if a user generates a second proof from the same Vault, he would not be able to claim the airdrop again since each proof generated from a Vault has the same vaultId
associated with it.
If you use Impersonation Mode, you will be able to claim the airdrop each time you try since the vaultId
is randomized in this mode.
The integration is basically done!
Ok, so if we recap an onchain Sismo Connect integration, it all comes to:
the creation of an app in the Sismo Factory to get an appId
a Sismo Connect configuration in the front end and the smart contract with this appId
and a possible "impersonation mode" enabled with chosen accounts for easy testing
the configuration of the React button to choose which proofs to request from your users
the creation of a smart contract to verify the user proofs onchain
Well, now that you have all these steps in mind, let's improve this airdrop contract by only allowing Gitcoin Passport holders to claim it.
The groupId
of the Gitcoin Passport Holders group is 0x1cde61966decb8600dfd0749bd371f12
. Let's add our claim request in the React button. We indicate the groupId of the group and the minimum value required in this group.
Once you have created this claim request in the front end, you also need to add it to the smart contract. Always remember that the proofs sent to the smart contract need to be checked with respect to some requests.
These simple code additions now allow our smart contract to only airdrop some tokens to holders of a Gitcoin Passport. While this is exciting, how can we quickly test it in our local front end if we are not Gitcoin Passport holders?
The simplest solution is to impersonate an account holding a Gitcoin Passport. Remember that we are already impersonating the leo21.sismo.eth Ethereum account that holds a Gitcoin Passport, making us eligible.
Don't forget to remove the vault object
in the config when deploying in production.
You don't need to do anything with anvil or your front-end application in your terminals. All is reloaded automatically for you. Just play with your front end by clicking on the "RESET" button in the top right! 😇
As you can see below, you are now asked to share your userId
like before, and you also should prove that you own a Gitcoin Passport. You also keep signing the address on which you want to receive the airdrop.
The interaction with the fork network can become quite unstable if you stop the yarn chain
command at some point or if you already used the sample app before.
You can end up with an infinitely pending transaction.
If so:
Keep the local anvil node running,
Make sure to delete your activity tab for the fork network in MetaMask by going to "Settings > Advanced > Clear activity tab data" when connected to the fork network.
Relaunch the anvil node and the application
Congrats again! You have successfully made your airdrop Sybil-resistant by gating it for holders of Gitcoin Passport.
Let's see how to ultimately combine data aggregation with privacy now by gating this Sybil-resistant airdrop to specific Sismo community members and allowing them to get more tokens depending on their reputation.
Data aggregation can be powerful in the context of an airdrop. For example, it can allow you to receive extra tokens if you prove some specific engagement in a community. In our example, we will offer more tokens to people that were early users of Sismo and to all the Sismo Factory users. Sismo Community members will also receive more tokens based on the value they have in the group.
To do this, we will simply do the same logic as before by creating additional claim requests for:
You can add the claim requests in the front end. Notice that to claim the airdrop, you must have a Gitcoin Passport and be a member of the Sismo Community, but it is not required to be an early contributor or a Factory user.
Add the claim requests in the smart contract:
Add the new function to calculate the number of tokens to airdrop based on the aggregated reputation:
You can try again to claim the airdrop from your application. You will see the auth request with the four claim requests and the sign message. If you share all the information by default, you should end up with 400 tokens!
And it is our final congrats! 🎉
If we recap, you managed to go from a simple request of vaultId to a complex multi-request of vaultId + group membership allowing you to create a Sybil-resistant airdrop from privately-aggregated data. All these requests respect user privacy since no Ethereum address is ever shared during the flow, thanks to data aggregation in Sismo's Data Vault.
If you have any questions about integrating Sismo Connect, don’t hesitate to reach out. The team will be happy to answer any questions you may have. Any feedback is also welcomed! If you want to fork a repository with complex requests already set up, you can check our onchain boilerplate.
Get involved in the Sismo community! ðŸŽ
This command starts the NextJs application that will call the contract in src/Airdrop.sol
which has already been deployed on your local fork of Mumbai. You should now have the simple tutorial application running on .
See the for more information.
To use Sismo Connect in your application, you will need to create an application in the and get its appId
. You can see a quick tutorial on how to do it .
You can spot the Sismo Connect configuration with the appId
of the application created in . You can learn more about the Sismo Connect configuration .
The library simplifies the Sismo Connect integration since it offers a React button to easily request proofs of user data.
Sismo users have a sovereign where they import Data Sources from which they will generate ZK proofs. Each Data Vault has a secret only known by its owner.
You can read more about it in
configuration.
Learn more about the Sismo Connect Config .
For more: check the , the library, and feel free to check the .
Our first aim is to make the ERC20 airdrop Sybil-resistant. To do this, we simply need to request a proof of Gitcoin Passport group membership from our users. We also want them to have a passport score above 15. You can request such a proof by taking the groupId
of the "Gitcoin Passport Holders" group that can be found on the Sismo Factory at this link: and create a from it.
You can learn how to create a Data Group with the .
When all of this is done, you can try again to go on your local application on to see the new proofs requested.
See for more information.
Sismo Community members with the id 0xd630aa769278cacde879c5c0fe5d203c
(you can see the group description in the Sismo Factory ). This membership is required.
Early Sismo Community members with the id 0xe4c011331d91b79639df349a93157a1b
(you can see the group description in the Sismo Factory ). This membership is optional and allows claimants to receive more tokens.
Sismo Factory Users with the id 0x05629c9a54e30d8c8aea911a48cd9e30
(you can see the group description in the Sismo Factory ). This membership is optional and allows users to receive more tokens.
To see how to deploy your contracts, you can go to the .
Look out for that we are participating in
Join our or our
See the