a16z / zkdrops Goto Github PK
View Code? Open in Web Editor NEWPrivate airdrops for Ethereum.
Home Page: https://a16z.com/2022/03/27/crypto-airdrop-privacy-tool-zero-knowledge-proofs/
License: GNU Affero General Public License v3.0
Private airdrops for Ethereum.
Home Page: https://a16z.com/2022/03/27/crypto-airdrop-privacy-tool-zero-knowledge-proofs/
License: GNU Affero General Public License v3.0
3 of these storage variables can be immutable
IERC20 public airdropToken;
uint public amountPerRedemption;
IPlonkVerifier verifier;
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?
the repo starts with a pre-existing set of key and secret here: https://github.com/a16z/zkp-merkle-airdrop-contracts/blob/main/test/temp/mt_keys_8192.csv
And it seems that these are basically just random 31 bytes generated here: https://github.com/a16z/zkp-merkle-airdrop-contracts/blob/722921f31ff32b332d7670486c0354f729d66bcb/utils/TestUtils.ts#L21
Would be ok to do the same in a customer facing app? Namely if I want a user to come to my platform and generate a commitment to be part of the airdrop, should it be also generated from random bytes?
enricobottazzi@MacBook-Air-di-Enrico --recurse-submodules % ./build_scripts/build_all.sh Error: Parse error on line 2: pragma circom 2.0.0;// Massively ---------------^ Expecting 'EOF', 'function', 'IDENTIFIER', '(', ')', 'template', ',', 'if', 'else', 'for', ';', 'while', 'do', 'compute', 'return', 'include', '{', '}', '==>', '-->', '===', '?', ':', '||', '&&', '|', '^', '&', '==', '!=', '<=', '>=', '<', '>', '<<', '>>', '+', '-', '*', '/', '\\', '%', '**', '++', '--', '!', '~', 'DECNUMBER', 'HEXNUMBER', 'var', 'signal', 'component', '[', ']', got '.' at Parser.parseError (/Users/enricobottazzi/.npm-global/lib/node_modules/circom/parser/jaz.js:620:21) at Parser.parse (/Users/enricobottazzi/.npm-global/lib/node_modules/circom/parser/jaz.js:687:22) at constructionPhase (/Users/enricobottazzi/.npm-global/lib/node_modules/circom/src/construction_phase.js:79:22) at compile (/Users/enricobottazzi/.npm-global/lib/node_modules/circom/src/compiler.js:71:5) at run (/Users/enricobottazzi/.npm-global/lib/node_modules/circom/cli.js:119:11) at Object.<anonymous> (/Users/enricobottazzi/.npm-global/lib/node_modules/circom/cli.js:140:1) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) at Module.load (internal/modules/cjs/loader.js:937:32) at Function.Module._load (internal/modules/cjs/loader.js:778:12) Parse error on line 2: pragma circom 2.0.0;// Massively ---------------^ Expecting 'EOF', 'function', 'IDENTIFIER', '(', ')', 'template', ',', 'if', 'else', 'for', ';', 'while', 'do', 'compute', 'return', 'include', '{', '}', '==>', '-->', '===', '?', ':', '||', '&&', '|', '^', '&', '==', '!=', '<=', '>=', '<', '>', '<<', '>>', '+', '-', '*', '/', '\\', '%', '**', '++', '--', '!', '~', 'DECNUMBER', 'HEXNUMBER', 'var', 'signal', 'component', '[', ']', got '.'
So upon running "npx hardhat compile" and "npx hardhat test", all of the tests pass normally (with existing keys and verification contract already generated in the repo).
But when regenerating the keys and verification contract by running "./build_scripts/build_all.sh", and then running "npx hardhat compile" and "npx hardhat test", the proof verification fails. This wasn't an issue a few months ago, but I suspect there's been an update to snarkjs/circom, or the solidity verifier contract that modifies the solidity call data. Nothing in your core repos / library has changed otherwise.
In any regard, if you try rerunning the test-cases in this repo, you'll find it fails. Double checked this on 2020 M1 and Ubuntu VM Instance (20.04) machines. Running circom v2.0.4, [email protected], node v16.15.0.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.