a16z / zkdrops

Private airdrops for Ethereum.

Home Page:https://a16z.com/2022/03/27/crypto-airdrop-privacy-tool-zero-knowledge-proofs/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Collecting airdrop with a locally created merkle tree of commitments

enricobottazzi opened this issue · comments

Hi,
rather than using the default merkle tree I'm creating a local merkle tree with only 4 commitments using the command ts-node ./scripts/gen_tree_from_file.ts <input filename> <output filename> <tree height>
I deploy the Airdrop contract with the new merkle tree root.

I, therefore, modified the collect script in this way:

// Collect against locally created merkle tree (only the first 4 commitments)
const hre = require("hardhat");
import { abi as ERC20_ABI } from "@openzeppelin/contracts/build/contracts/ERC20.json";
import { BigNumber, Contract } from "ethers";
import { abi as PRIVATE_AIRDROP_ABI } from "../artifacts/contracts/PrivateAirdrop.sol/PrivateAirdrop.json"
import { readFileSync } from "fs";
import { readMerkleTreeAndSourceFromFile } from "../utils/TestUtils";
import { generateProofCallData, pedersenHash, toHex } from "zkp-merkle-airdrop-lib";

/** Collect an airdrop from the local merkle tree against deployed contract. */
async function main() {
    let WASM_PATH = "./build/circuit_js/circuit.wasm";
    let ZKEY_PATH = "./build/circuit_final.zkey";

    let WASM_BUFF = readFileSync(WASM_PATH);
    let ZKEY_BUFF = readFileSync(ZKEY_PATH);

    let ERC20_ADDR = "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0";
    let AIRDROP_ADDR = "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9";
    let MT_KEYS_PATH = "./test/temp/local_mk.csv";

    let [collector] = await hre.ethers.getSigners();

    let merkleTreeAndSource = readMerkleTreeAndSourceFromFile(MT_KEYS_PATH);
    let redeemIndex = 1;
    let key = merkleTreeAndSource.leafNullifiers[redeemIndex];
    let secret = merkleTreeAndSource.leafSecrets[redeemIndex];
    let proof = 
        await generateProofCallData(
            merkleTreeAndSource.merkleTree, 
            key, 
            secret, 
            collector.address,
            WASM_BUFF,
            ZKEY_BUFF);
    console.log("Proof: ", proof);

    let keyHash = toHex(pedersenHash(key));

    let airdropContract = new Contract(AIRDROP_ADDR, PRIVATE_AIRDROP_ABI, collector);
    let tx = await airdropContract.collectAirdrop(proof, keyHash);
    await tx.wait();
    console.log("Collected!")
    

    let erc20Contract = new Contract(ERC20_ADDR, ERC20_ABI, collector.provider!);
    let balance: BigNumber = await erc20Contract.balanceOf(collector.address)
    console.log(`Collector balance: ${balance.toString()}`)
}

main().then(() => process.exit(0))
    .catch(e => {
        console.error(e);
        process.exit(-1);
    })

When running the script I get some problems in generating the proof

enricobottazzi@MacBook-Air-di-Enrico zkp-merkle-airdrop-contracts % npx hardhat run --network localhost scripts/collect3.ts
No need to generate any newer typings.
Error: Not all inputs have been set. Only 9 out of 31
    at WitnessCalculator.<anonymous> (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:160:27)
    at step (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:33:23)
    at Object.next (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:14:53)
    at /Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:4:12)
    at WitnessCalculator._doCalculateWitness (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:131:16)
    at WitnessCalculator.<anonymous> (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:220:51)
    at step (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:33:23)
    at Object.next (/Users/enricobottazzi/REPOS/zkp-merkle-airdrop-contracts/zkp-merkle-airdrop-lib/lib/witness_calculator.js:14:53)

Why is that?