Browse Source

Add ETH deposit & withdraw

pull/2/head
arnaucube 4 years ago
parent
commit
d6568e9f0a
5 changed files with 58 additions and 25 deletions
  1. +9
    -0
      circuits/withdraw.circom
  2. +10
    -6
      contracts/Miksi.sol
  3. +11
    -10
      contracts/verifier.sol
  4. +2
    -1
      test/circuits/withdraw.test.ts
  5. +26
    -8
      test/contracts/miksi.test.ts

+ 9
- 0
circuits/withdraw.circom

@ -11,6 +11,10 @@ PUB_amount+--------->+Poseidon+------->+ == +<-----+PUB_commitment
PRI_secret+--------->+ |
+--------+
+----+
PUB_address+--->+ != +<---+0
+----+
*/
@ -27,6 +31,7 @@ template Withdraw() {
signal input amount;
signal input commitment;
signal private input secret;
signal input address;
component hash = Poseidon(3, 6, 8, 57);
hash.inputs[0] <== coinCode;
@ -37,6 +42,10 @@ template Withdraw() {
eq.in[0] <== hash.out;
eq.in[1] <== commitment;
eq.out === 1;
component z = IsZero();
z.in <== address;
z.out === 0;
}
component main = Withdraw();

+ 10
- 6
contracts/Miksi.sol

@ -18,10 +18,10 @@ contract Miksi {
function deposit(
uint256 coinCode,
uint256 amount,
// uint256 amount,
uint256 commitment
) public {
deposits[commitment] = Deposit(coinCode, amount);
) public payable {
deposits[commitment] = Deposit(coinCode, msg.value);
}
function getDeposit(
@ -35,18 +35,22 @@ contract Miksi {
function withdraw(
uint256 commitment,
address payable _address,
uint[2] memory a,
uint[2][2] memory b,
uint[2] memory c
) public {
uint256[3] memory input = [
uint256[4] memory input = [
deposits[commitment].coinCode,
deposits[commitment].amount,
commitment
commitment,
uint256(_address)
];
require(verifier.verifyProof(a, b, c, input), "zkProof withdraw could not be verified");
// zk verification passed, proceed with the withdraw
_address.send(deposits[commitment].amount);
// _address.call.value(deposits[commitment].amount).gas(20317)();
}
}

+ 11
- 10
contracts/verifier.sol

@ -174,15 +174,16 @@ contract Verifier {
Pairing.G1Point C;
}
function verifyingKey() internal pure returns (VerifyingKey memory vk) {
vk.alfa1 = Pairing.G1Point(14097801211944906051089174223297219347615673653483074396722237348255135354793,11521805996213505094241296676841118790602800394351210524781678600259635687017);
vk.beta2 = Pairing.G2Point([10568113084382768459048600842325733541704319994390569016962727798975578285556,12153127494717088082185264166292331483064881810067105818973650106079389053760], [15466853815350922606512198371753750557123426982658771465057849995060646541965,19455599286846641316750628844277996370086220302684811162394897510245086369063]);
vk.gamma2 = Pairing.G2Point([9953206108281020354042857864759150528133680155656326486566810703438203105960,2135441618643414785978676900143212634198799871478347410262755821177928527954], [12268954056182736147684854354337352872362113322749551731236862327324643375709,1876815956335882350254399331991656204647508838653345904292805224558359111754]);
vk.delta2 = Pairing.G2Point([2663201400823710456782609562902977142452976016992514856722909325946187937310,14978203394907966123099039365683754435614065359984166192966572314168591418734], [21214052898049569224905859982289894645182104181183009284067141977584101227593,5359205214835186177822827375213125847159194113298572556544149883988483807673]);
vk.IC = new Pairing.G1Point[](4);
vk.IC[0] = Pairing.G1Point(13408366362878504901998541398762720605356468458453065115215476638573116973612,5444591120479812671974498312523952995185895771090546719531123873877970703107);
vk.IC[1] = Pairing.G1Point(17521475475731634509173671006849258017401865133255449322161532195113052551951,9591040297172512635747124918118916335434286018868426662476696440648139959562);
vk.IC[2] = Pairing.G1Point(10318918062415458864931153468077926819897264015796609757736600478356825989809,2525805381962488186604363053663950289666098935158384096965441697921773574413);
vk.IC[3] = Pairing.G1Point(12285798798872837559598057721617037310744162378880792291377164843222236229469,16499092667373175512569946766276627516609608654521959670983218776858111396618);
vk.alfa1 = Pairing.G1Point(5185992386807636752062921178966578257539151042202977558020078229066726353735,19116203848700332781926088278955228321025476213248649030230870938462300903297);
vk.beta2 = Pairing.G2Point([19030978247664556689560141272090896525855193446598104251860042964819095406467,19780960404766112404848074878225825567855499848739061882556607695385088991192], [20402461031267926255530100927046942331147898484488092600018001239630447470368,17604138488196164031519027655960050500952176071938159024932979559575610655320]);
vk.gamma2 = Pairing.G2Point([20383216224167453593158000496263161259331265217720672612685782338425828607013,12285091765781487940062490824680322009247635572831566743154406937445855014141], [2724044019507218108155409647671037824297854833037683233209628555415178462971,4800441398018446385507678136399891972502082696226688244556543968658013445721]);
vk.delta2 = Pairing.G2Point([17491660837811889973732218736865963003206037853732483884984507582280081743890,18194603073278150162885840058572458854817989194824624275670491325570842555401], [14259520890547064112120136619441621870946603290427647212804054747278532372550,14237711745170441984980821720645206187129227373288931343140891164943633394176]);
vk.IC = new Pairing.G1Point[](5);
vk.IC[0] = Pairing.G1Point(5800430773422603830326865012746294458553705291090306505082228589953960548435,525261600745641876890318660619064985918284670178585976847597013044968033805);
vk.IC[1] = Pairing.G1Point(13962429114312903407632291539456657530314035590343134693033142826413285622014,9649969769508662299834286176418790329944910509961747776147748835638371066986);
vk.IC[2] = Pairing.G1Point(15449758800146945182032375987369505286936830519651791301171981724664755129658,20429634243561140221481565627307606983692378272988345590135001254474940660921);
vk.IC[3] = Pairing.G1Point(6593016958529739953865018414912427672210776178723941512691424600884151791016,2330860586625886543272754640931712670362458263865839970599736410727810605340);
vk.IC[4] = Pairing.G1Point(17799933908098896756054489526152304776886935915002907298028930270007186443766,16808221405053081411172376396342768077671335058872875437488630198515891174714);
}
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
@ -208,7 +209,7 @@ contract Verifier {
uint[2] memory a,
uint[2][2] memory b,
uint[2] memory c,
uint[3] memory input
uint[4] memory input
) public view returns (bool r) {
Proof memory proof;
proof.A = Pairing.G1Point(a[0], a[1]);

+ 2
- 1
test/circuits/withdraw.test.ts

@ -29,7 +29,8 @@ describe("withdraw test", function () {
"coinCode": coinCode,
"amount": amount,
"commitment": commitment,
"secret": secret
"secret": secret,
"address": "987654321"
});
await circuit.checkConstraints(witness);
});

+ 26
- 8
test/contracts/miksi.test.ts

@ -15,9 +15,9 @@ contract("miksi", (accounts) => {
const {
0: owner,
1: idEth1,
2: idEth2,
3: idEth3,
1: addr1, // used for the deposit
2: addr2, // used for the withdraw
3: addr3,
} = accounts;
let insVerifier;
@ -32,14 +32,24 @@ contract("miksi", (accounts) => {
it("miksi flow", async () => {
const secret = "123456789";
const coinCode = "1";
const amount = "100";
const coinCode = "0"; // refearing to ETH
const ethAmount = '0.5';
const amount = web3.utils.toWei(ethAmount, 'ether');
let balance_wei = await web3.eth.getBalance(addr1);
console.log("Balance at " + addr1, web3.utils.fromWei(balance_wei, 'ether'));
expect(balance_wei).to.be.equal('100000000000000000000');
const poseidon = circomlib.poseidon.createHash(6, 8, 57);
const commitment = poseidon([coinCode, amount, secret]).toString();
// deposit
await insMiksi.deposit(coinCode, amount, commitment);
console.log("Deposit of " + ethAmount + " ETH from " + addr1);
await insMiksi.deposit(coinCode, commitment, {from: addr1, value: amount});
balance_wei = await web3.eth.getBalance(addr1);
console.log("Balance at " + addr1, web3.utils.fromWei(balance_wei, 'ether'));
expect(balance_wei).to.be.equal('99499141300000000000');
// getDeposit data
const res = await insMiksi.getDeposit(commitment);
@ -53,9 +63,11 @@ contract("miksi", (accounts) => {
"coinCode": coinCode,
"amount": amount,
"commitment": commitment,
"secret": secret
"secret": secret,
"address": addr2
});
const options = {};
console.log("Calculate witness");
const wc = await WitnessCalculatorBuilder(wasm, options);
const w = await wc.calculateWitness(input);
const witness = unstringifyBigInts(stringifyBigInts(w));
@ -63,11 +75,14 @@ contract("miksi", (accounts) => {
// generate zkproof of commitment using snarkjs (as is a test)
const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync("./build/proving_key.json", "utf8")));
console.log("Generate zkSNARK proof");
const {proof, publicSignals} = groth.genProof(provingKey, witness);
// withdraw
console.log("Withdraw of " + ethAmount + " ETH to " + addr2);
const resW = await insMiksi.withdraw(
commitment,
addr2,
[proof.pi_a[0].toString(), proof.pi_a[1].toString()],
[
[proof.pi_b[0][1].toString(), proof.pi_b[0][0].toString()],
@ -75,7 +90,10 @@ contract("miksi", (accounts) => {
],
[proof.pi_c[0].toString(), proof.pi_c[1].toString()]
);
console.log("resW", resW);
// console.log("resW", resW);
balance_wei = await web3.eth.getBalance(addr2);
console.log("Balance at " + addr2, web3.utils.fromWei(balance_wei, 'ether'));
expect(balance_wei).to.be.equal('100500000000000000000');
});
});

Loading…
Cancel
Save