arnaucube
arnaucube/miksi-corePublic Self-hosted repository
miksi-core/test/contracts/miksi.test.ts
test/contracts/miksi.test.tsRaw
  1const Verifier = artifacts.require("../../contracts/Verifier");
  2const Miksi = artifacts.require("../../contracts/Miksi.sol");
  3
  4const chai = require("chai");
  5const expect = chai.expect;
  6const truffleAssert = require('truffle-assertions');
  7
  8const fs = require("fs");
  9const { groth } = require('snarkjs');
 10const { stringifyBigInts, unstringifyBigInts } = require('ffjavascript').utils;
 11const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
 12const circomlib = require("circomlib");
 13
 14contract("miksi", (accounts) => {
 15
 16
 17  const {
 18    0: owner,
 19    1: addr1, // used for the deposit
 20    2: addr2, // used for the withdraw
 21    3: addr3,
 22  } = accounts;
 23
 24  let insVerifier;
 25  let insMiksi;
 26
 27  before(async () => {
 28
 29    insVerifier = await Verifier.new();
 30    insMiksi = await Miksi.new(insVerifier.address);
 31  });
 32
 33  it("miksi flow", async () => {
 34    const secret = "123456789";
 35
 36    const coinCode = "0"; // refearing to ETH
 37    const ethAmount = '0.5';
 38    const amount = web3.utils.toWei(ethAmount, 'ether');
 39
 40    let balance_wei = await web3.eth.getBalance(addr1);
 41    console.log("Balance at " + addr1, web3.utils.fromWei(balance_wei, 'ether'));
 42    expect(balance_wei).to.be.equal('100000000000000000000');
 43
 44    const poseidon = circomlib.poseidon.createHash(6, 8, 57);
 45    const commitment = poseidon([coinCode, amount, secret]).toString();
 46
 47    // deposit
 48    console.log("Deposit of " + ethAmount + " ETH from " + addr1);
 49    await insMiksi.deposit(coinCode, commitment, {from: addr1, value: amount});
 50
 51    balance_wei = await web3.eth.getBalance(addr1);
 52    console.log("Balance at " + addr1, web3.utils.fromWei(balance_wei, 'ether'));
 53    expect(balance_wei).to.be.equal('99499107180000000000');
 54
 55    // getDeposit data
 56    const res = await insMiksi.getDeposit(commitment);
 57    expect(res[0].toString()).to.be.equal(coinCode);
 58    expect(res[1].toString()).to.be.equal(amount);
 59
 60
 61    // calculate witness
 62    const wasm = await fs.promises.readFile("./build/withdraw.wasm");
 63    const input = unstringifyBigInts({
 64      "coinCode": coinCode,
 65      "amount": amount,
 66      "commitment": commitment,
 67      "secret": secret,
 68      "address": addr2
 69    });
 70    const options = {};
 71    console.log("Calculate witness");
 72    const wc = await WitnessCalculatorBuilder(wasm, options);
 73    const w = await wc.calculateWitness(input);
 74    const witness = unstringifyBigInts(stringifyBigInts(w));
 75
 76    // generate zkproof of commitment using snarkjs (as is a test)
 77    const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./build/proving_key.json", "utf8")));
 78
 79    console.log("Generate zkSNARK proof");
 80    const {proof, publicSignals} = groth.genProof(provingKey, witness);
 81
 82    // withdraw
 83    console.log("Withdraw of " + ethAmount + " ETH to " + addr2);
 84    let resW = await insMiksi.withdraw(
 85      commitment, 
 86      addr2,
 87      [proof.pi_a[0].toString(), proof.pi_a[1].toString()],
 88      [
 89        [proof.pi_b[0][1].toString(), proof.pi_b[0][0].toString()],
 90        [proof.pi_b[1][1].toString(), proof.pi_b[1][0].toString()]
 91      ],
 92      [proof.pi_c[0].toString(), proof.pi_c[1].toString()]
 93    );
 94    // console.log("resW", resW);
 95
 96    balance_wei = await web3.eth.getBalance(addr2);
 97    console.log("Balance at " + addr2, web3.utils.fromWei(balance_wei, 'ether'));
 98    expect(balance_wei).to.be.equal('100500000000000000000');
 99
100    console.log("Try to reuse the zkproof and expect revert");
101    await truffleAssert.fails(
102      insMiksi.withdraw(
103        commitment, 
104        addr2,
105        [proof.pi_a[0].toString(), proof.pi_a[1].toString()],
106        [
107          [proof.pi_b[0][1].toString(), proof.pi_b[0][0].toString()],
108          [proof.pi_b[1][1].toString(), proof.pi_b[1][0].toString()]
109        ],
110        [proof.pi_c[0].toString(), proof.pi_c[1].toString()]
111      ),
112      truffleAssert.ErrorType.REVERT,
113      "deposit already withdrawed"
114    );
115    balance_wei = await web3.eth.getBalance(addr2);
116    expect(balance_wei).to.be.equal('100500000000000000000');
117  });
118});