Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/enricobottazzi/zeko

Zero Knowledge-based NFT Private Airdrop. 🏆 finalist EthDenver 22
https://github.com/enricobottazzi/zeko

circom erc721 ethereum identity zero-knowledge

Last synced: 9 days ago
JSON representation

Zero Knowledge-based NFT Private Airdrop. 🏆 finalist EthDenver 22

Awesome Lists containing this project

README

        

# Zero Knowledge Proof NFT Airdrop

This library contains the tools (Zero Knowledge Proof circuits + smart contracts) needed to run a Zero Knowledge Based NFT Airdrop.
DAOs or any other entity can collect commitments from their contributors via web2 platforms in a public way and deploy a private airdrop smart contract that allows these same contributors to use their wallet to redeem their airdrop.

By leveraging Zero Knowledge proof, there is no association between the web2 identity that made the initial commitment and the web3 wallet used to redeem the NFT based on that same commitment

Project finalist at EthDenver 2022 🙌

[Miro board to understand how it works](https://miro.com/app/board/uXjVOCOM9cg=/?invite_link_id=79946175165)

## Related Work and Credits

Credit to A16Z (https://github.com/a16z/zkp-merkle-airdrop-contracts). This application modifies the purpose of the core A16Z repo allowing NFT (ERC721) private airdrops as well.

## Purpose

Distribute an NFT airdrop without having to collect users address beforehand. Today is very common to see DAOs and other NFT projects asking for the public addresses of their contributors via Google Forms or Airtables in order to run aidrops. **This it is a privacy threat for users**.

# Usage

### Setup

- `npm i` to install all the support node packages
- Circom setup in order to generate circuits: [Circom 2.0 install + snarkjs](https://docs.circom.io/getting-started/installation/)
- [Hardhat configuration](https://www.chainshot.com/article/hardhat-guides-setup)

### Compile circom circuits and solidity verifier smart contract

- Compile the circuit.circom file. Note: the input in the last line must match the height of the merkle tree. The number of leaves is the amount of commitments you are gonna collect from the users `circom circuits/circuit.circom --sym --wasm --r1cs -o ./build`
- generate zkey => `snarkjs plonk setup build/circuit.r1cs build/pot16_final.ptau build/circuit_final.zkey`
- generate MerkVerifier.sol => `snarkjs zkey export solidityverifier build/circuit_final.zkey contracts/compiled/MerkVerifier.sol`

### Deploy smart contracts

- `npx hardhat run ./scripts/4_deployContracts.ts --network localhost`

By doing that we deploy 3 core contracts:
1. ZekoGenerativeNFT.sol, an ERC721 generative NFT contract.
(it can be any already existing ERC721 standard compatible contract)
2. PrivateAirdrop.sol, used to manage the airdrop.
3. MerkVerifier.sol, contract automatically generated by circom as a result of the input circuit. It is used to run the zero knowledge proof verification on-chain.

### Mint NFTs

- `npx hardhat run ./scripts/5_mint721.ts --network localhost`

By doing that a set of NFTs is minted and transferred to the privateAirdrop contract.

An extra functionality added on ZekoGenerativeNFT.sol (function mintRoleToAirdrop) allows to mint a generative NFT that include a DaoName and a role as on-chain metadata.

Note: this function is not strictly required to the execution of the private airdrop.

### Collect Commitments

- `npx hardhat run ./scripts/6_collectCommitments.ts --network localhost`

This script simulates the collection of users' commitments by the entity which is gonna execute the airdrop.

A commitment is generated from the uses by hashing two private values (a secret and a nullifier). The commitments are collected by the airdrop issuer entity and assembled in a merkle tree. The root of the commitments merkle tree is then stored as state variable in the private airdrop contract.

The commitments are stored (and dynamically updated) into ./public/publicCommitments.txt

### Generate Zero Knowledge Proof Call Data

- `npx hardhat run ./scripts/7_GenerateProofCallData.ts --network localhost`

This script simulates a user that, starting from:
- his/her secret and private nullifier used to creates the commitment (private)
- the public verification key (circuit_final.zkey) - (public)
- the public zero knowledge circuit (circuit.wasm) - (public)

is able to generate the proof and the nullifierHash needed to prove their eligibility for the airdrop.

Note: this operation doesn't involve any on-chain transaction and can be privately by the user or in any browser facing app.

Note: the nullifier hash is generated to avoid the double spending starting from the same (valid) proof

### Collect the airdrop

- `npx hardhat run ./scripts/8_collect721.ts --network localhost`

The user calls the collectAirdrop passing the proof and the nullifierHash as inputs.

Again, the verification process performed by the MerkVerifier contract is able to tell if the inputs passed by the users are associated to any of the commitments used to assemble the merkle tree without revealing which specific commitment is associated with the user that makes the call.
**The privacy of the user is protected**

## Check the contracts deployed on Mumbai (Polygon testned)

- [ZekoGenerativeNFT.sol](https://mumbai.polygonscan.com/address/0xbA7B88DF383728FAe73F4aC6532795797202cc87#code)
- [MerkVerifier.sol](https://mumbai.polygonscan.com/address/0x0B27cc41F37e62Bfea1f4E42897D56B5A18a3E70#code)
- [PrivateAirdrop.sol]()

## Use-cases

- Collect users' commitments via off-chain public channels and distribute airdrop preserving their privacy

- Create identity-based NFT badges that bridge off-chain credentials to on-chain identity in a privacy preserving way(Zero Knowledge based badges created according to someone's role on Discord or Github contribution). This would further then unlock:

- Improved governance mechanism such as weighting the voting power according to these badges
- Automated distribution of grants based on badge ownership
- Use these badges as sybil-resistant authentication mechanism

## To test the contract

- Start your localhost `npx hardhat node`
- Run the test `npx hardhat test ./test/smartContractTest.js --network localhost`

## Demo

[Youtube](https://www.youtube.com/watch?v=PnffMSrQDlY)