arnaucube
arnaucube/miksi-appPublic Self-hosted repository
miksi-app/index.js
index.jsRaw
  1var circuit = {};
  2var provingKey = {};
  3var witnessCalc = {};
  4const abi = JSON.parse(`[{"inputs":[{"internalType":"address","name":"_depositVerifierContractAddr","type":"address"},{"internalType":"address","name":"_withdrawVerifierContractAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_commitment","type":"uint256"},{"internalType":"uint256","name":"_root","type":"uint256"},{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getCommitments","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_address","type":"address"},{"internalType":"uint256","name":"nullifier","type":"uint256"},{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]`);
  5const miksiAddress = "0x6E77f4bB1356426baD1Bd014d04388eFAc197Fe1";
  6
  7function loadCircuit(circuitname) {
  8  fetch("circuits-files/"+circuitname+"-proving_key.bin").then( (response) => {
  9    return response.arrayBuffer();
 10  }).then( (b) => {
 11    provingKey[circuitname] = b;
 12    console.log("proving_key loaded for", circuitname);
 13  });
 14
 15  fetch("circuits-files/"+circuitname+".wasm").then( (response) => {
 16    return response.arrayBuffer();
 17  }).then( (b) => {
 18    witnessCalc[circuitname] = b;
 19    console.log("w", b);
 20    console.log("witnessCalc loaded for", circuitname);
 21  });
 22}
 23
 24async function deposit(circuitname) {
 25  document.getElementById("depositRes").innerHTML = `
 26    Generating zkProof & making the deposit
 27  `;
 28  console.log("circuit:", circuitname);
 29
 30  // TODO
 31  const secret = "1234567890";
 32  const nullifier = "567891234";
 33  const commitments = [];
 34  // getCommitments from the tree
 35
 36  // calculate witness
 37  console.log(witnessCalc[circuitname]);
 38  const cw = await miksi.calcWitness(witnessCalc[circuitname], secret, nullifier, commitments);
 39  const witness = cw.witness;
 40  const publicInputs = cw.publicInputs;
 41  console.log("w", witness);
 42  console.log("pi", publicInputs);
 43
 44  // generate proof
 45  const start = new Date().getTime();
 46  console.log(provingKey[circuitname]);
 47  const proof = await window.groth16GenProof(witness.buffer, provingKey[circuitname]);
 48  const end = new Date().getTime();
 49  const time = end - start;
 50  console.log("circuit " + circuitname + " took " + time + "ms to compute");
 51  console.log(proof);
 52
 53
 54  // send tx
 55  const accounts = await web3.eth.getAccounts();
 56  const sender = accounts[0];
 57  console.log("SENDER", sender);
 58
 59  console.log("sc call data",
 60    publicInputs.commitment,
 61    publicInputs.root.toString(),
 62    [proof.pi_a[0], proof.pi_a[1]],
 63    [
 64      [proof.pi_b[0][1], proof.pi_b[0][0]],
 65      [proof.pi_b[1][1], proof.pi_b[1][0]]
 66    ],
 67    [proof.pi_c[0], proof.pi_c[1]],
 68  );
 69  miksiContract.methods.deposit(
 70    publicInputs.commitment,
 71    publicInputs.root.toString(),
 72    [proof.pi_a[0], proof.pi_a[1]],
 73    [
 74      [proof.pi_b[0][1], proof.pi_b[0][0]],
 75      [proof.pi_b[1][1], proof.pi_b[1][0]]
 76    ],
 77    [proof.pi_c[0], proof.pi_c[1]],
 78  ).send(
 79    {from: sender, value: 1000000000000000000},
 80    function(error, transactionHash){
 81      console.log("https://goerli.etherscan.io/tx/"+transactionHash);
 82      console.log(error);
 83    });
 84
 85  // print secret & nullifier
 86  document.getElementById("depositRes").innerHTML = `
 87    Secret: <b>`+secret+`</b><br>
 88    Nullifier: <b>`+nullifier+`</b><br>
 89  `;
 90}
 91
 92loadCircuit("deposit");
 93loadCircuit("withdraw");
 94
 95
 96
 97
 98let miksiContract;
 99
100function connectMetamask() {
101  const ethEnabled = () => {
102    if (window.web3) {
103      window.web3 = new Web3(window.web3.currentProvider);
104      window.ethereum.enable();
105      return true;
106    }
107    return false;
108  }
109
110  if (!ethEnabled()) {
111    alert("Please install MetaMask to use miksi");
112  }
113
114  console.log("abi", abi);
115  miksiContract = new web3.eth.Contract(abi, miksiAddress);
116  console.log("miksiContract", miksiContract);
117
118  web3.eth.getBalance("0x35d4dCDdB728CeBF80F748be65bf84C776B0Fbaf", function(err, res){console.log("BAL", JSON.stringify(res));});
119
120  miksiContract.methods.getCommitments().call()
121    .then(console.log);
122}