diff --git a/css/dark-theme.css b/css/dark-theme.css
index 05ce12a..56e3a5f 100644
--- a/css/dark-theme.css
+++ b/css/dark-theme.css
@@ -6,15 +6,16 @@
.card,
.list-group-item,
input,
+ textarea,
.nav-link {
background: none!important;
border-color: #3b4145;
}
-.dark-theme input {
- color: #FF00B9;
+.dark-theme input, textarea {
+ color: #FF00B9!important;
}
-.dark-theme input:focus {
- color: #FF00B9;
+.dark-theme input:focus, textarea:focus {
+ color: #FF00B9!important;
box-shadow: 0px 0px 5px #FF00B9!important;
border: none;
}
diff --git a/index.html b/index.html
index 620c1bb..6590f7c 100644
--- a/index.html
+++ b/index.html
@@ -67,7 +67,7 @@
Quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
-
+
@@ -76,9 +76,9 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.
-
+
-
+
diff --git a/index.js b/index.js
index fdc5653..036ee42 100644
--- a/index.js
+++ b/index.js
@@ -2,7 +2,8 @@ var circuit = {};
var provingKey = {};
var witnessCalc = {};
const 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"}]`);
-const miksiAddress = "0x6E77f4bB1356426baD1Bd014d04388eFAc197Fe1";
+// const miksiAddress = "0x6E77f4bB1356426baD1Bd014d04388eFAc197Fe1";
+const miksiAddress = "0xc9009d9Df413883B6064503FDA93A7A8ab9B7afb";
function loadCircuit(circuitname) {
fetch("circuits-files/"+circuitname+"-proving_key.bin").then( (response) => {
@@ -28,18 +29,20 @@ async function deposit(circuitname) {
console.log("circuit:", circuitname);
// TODO
- const secret = "1234567890";
- const nullifier = "567891234";
+ const secret = miksi.randBigInt().toString();
+ const nullifier = miksi.randBigInt().toString();
+ // const secret = "1234567890";
+ // const nullifier = "5678901234";
const commitments = [];
// getCommitments from the tree
// calculate witness
console.log(witnessCalc[circuitname]);
- const cw = await miksi.calcWitness(witnessCalc[circuitname], secret, nullifier, commitments);
+ const cw = await miksi.calcDepositWitness(witnessCalc[circuitname], secret, nullifier, commitments);
const witness = cw.witness;
const publicInputs = cw.publicInputs;
console.log("w", witness);
- console.log("pi", publicInputs);
+ console.log("publicInputs", publicInputs);
// generate proof
const start = new Date().getTime();
@@ -82,10 +85,89 @@ async function deposit(circuitname) {
console.log(error);
});
+ // print secret & nullifier
+ let jw = {
+ secret: secret,
+ nullifier: nullifier
+ };
+ console.log("jw", JSON.stringify(jw));
+ document.getElementById("depositRes").innerHTML = `
+ Please store the secret data in a safe place:
+
+
+ `;
+}
+
+async function withdraw(circuitname) {
+ document.getElementById("withdrawRes").innerHTML = `
+ Generating zkProof & making the withdraw
+ `;
+ console.log("circuit:", circuitname);
+ const jw = JSON.parse(document.getElementById("jsonWithdraw").value);
+ const secret = jw.secret;
+ const nullifier = jw.nullifier;
+ console.log(secret, nullifier);
+ const commitment = miksi.calcCommitment(secret, nullifier);
+
+ // getCommitments from the tree
+ let res = await miksiContract.methods.getCommitments().call();
+ console.log("res", res);
+ const commitments = res[0];
+ console.log("commitments", commitments);
+
+ // calculate witness
+ console.log(witnessCalc[circuitname]);
+ const proverAccounts = await web3.eth.getAccounts();
+ const addr = proverAccounts[0];
+ const cw = await miksi.calcWithdrawWitness(witnessCalc[circuitname], secret, nullifier, commitments, addr);
+ const witness = cw.witness;
+ const publicInputs = cw.publicInputs;
+ console.log("w", witness);
+ console.log("publicInputs", publicInputs);
+
+ // generate proof
+ const start = new Date().getTime();
+ console.log(provingKey[circuitname]);
+ const proof = await window.groth16GenProof(witness.buffer, provingKey[circuitname]);
+ const end = new Date().getTime();
+ const time = end - start;
+ console.log("circuit " + circuitname + " took " + time + "ms to compute");
+ console.log(proof);
+
+
+ // send tx
+ const accounts = await web3.eth.getAccounts();
+ const sender = accounts[0];
+ console.log("SENDER", sender);
+
+ console.log("sc call data",
+ publicInputs.address,
+ publicInputs.nullifier,
+ [proof.pi_a[0], proof.pi_a[1]],
+ [
+ [proof.pi_b[0][1], proof.pi_b[0][0]],
+ [proof.pi_b[1][1], proof.pi_b[1][0]]
+ ],
+ [proof.pi_c[0], proof.pi_c[1]],
+ );
+ miksiContract.methods.withdraw(
+ publicInputs.address,
+ publicInputs.nullifier,
+ [proof.pi_a[0], proof.pi_a[1]],
+ [
+ [proof.pi_b[0][1], proof.pi_b[0][0]],
+ [proof.pi_b[1][1], proof.pi_b[1][0]]
+ ],
+ [proof.pi_c[0], proof.pi_c[1]],
+ ).send(
+ {from: sender},
+ function(error, transactionHash){
+ console.log("https://goerli.etherscan.io/tx/"+transactionHash);
+ console.log(error);
+ });
+
// print secret & nullifier
document.getElementById("depositRes").innerHTML = `
- Secret: `+secret+`
- Nullifier: `+nullifier+`
`;
}
@@ -97,7 +179,7 @@ loadCircuit("withdraw");
let miksiContract;
-function connectMetamask() {
+async function connectMetamask() {
const ethEnabled = () => {
if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider);
@@ -115,8 +197,8 @@ function connectMetamask() {
miksiContract = new web3.eth.Contract(abi, miksiAddress);
console.log("miksiContract", miksiContract);
- web3.eth.getBalance("0x35d4dCDdB728CeBF80F748be65bf84C776B0Fbaf", function(err, res){console.log("BAL", JSON.stringify(res));});
+ const acc = await web3.eth.getAccounts();
+ const addr = acc[0];
+ web3.eth.getBalance(addr, function(err, res){console.log("BAL", JSON.stringify(res));});
- miksiContract.methods.getCommitments().call()
- .then(console.log);
}
diff --git a/lib/miksi-browser.js b/lib/miksi-browser.js
index 590e460..de621ea 100644
--- a/lib/miksi-browser.js
+++ b/lib/miksi-browser.js
@@ -76276,12 +76276,12 @@ function extend() {
const fs = require("fs");
const bigInt = require("big-integer");
const { groth } = require('snarkjs');
+const { Fr } = require('ffjavascript').bn128;
const { stringifyBigInts, unstringifyBigInts } = require('ffjavascript').utils;
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
const circomlib = require("circomlib");
const smt = require("circomlib").smt;
const Web3 = require("web3");
-// const buildBn128 = require("wasmsnark").buildBn128;
const nLevels = 5;
@@ -76289,18 +76289,26 @@ const coinCode = "0"; // refearing to ETH
const ethAmount = '1';
const amount = Web3.utils.toWei(ethAmount, 'ether');
-// let bn128;
-//
-// exports.init = async () => {
-// bn128 = await buildBn128();
-// }
+exports.randBigInt = () => {
+ return Fr.random();
+};
-exports.calcWitness = async (wasm, secret, nullifier, commitments) => {
+exports.calcCommitment = (secret, nullifier) => {
const poseidon = circomlib.poseidon.createHash(6, 8, 57);
const commitment = poseidon([coinCode, amount, secret, nullifier]).toString();
+ return commitment;
+};
+exports.calcDepositWitness = async (wasm, secret, nullifier, commitments) => {
+ const poseidon = circomlib.poseidon.createHash(6, 8, 57);
+ const commitment = poseidon([coinCode, amount, secret, nullifier]).toString();
+
+ // rebuild the tree
let tree = await smt.newMemEmptyTrie();
await tree.insert(1, 0);
+ for (let i=0; i {
};
}
+exports.calcWithdrawWitness = async (wasm, secret, nullifier, commitments, addr) => {
+ const poseidon = circomlib.poseidon.createHash(6, 8, 57);
+ const commitment = poseidon([coinCode, amount, secret, nullifier]).toString();
+
+ // rebuild the tree
+ let tree = await smt.newMemEmptyTrie();
+ await tree.insert(1, 0);
+ for (let i=0; i