Skip to content

Commit

Permalink
Merge pull request #3 from cryptphitraining/merkle-updated
Browse files Browse the repository at this point in the history
Merkle updated
  • Loading branch information
cryptphitraining authored Jun 26, 2024
2 parents 83d66ce + cf555aa commit 7afb7ae
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 38 deletions.
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": 1,
"deployAliases": {}
}
}
15 changes: 12 additions & 3 deletions src/ZKLottoGame.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AccountUpdate, Field, Mina, PrivateKey, PublicKey, Signature } from 'o1js';
import { AccountUpdate, Field, Mina, PrivateKey, PublicKey, Signature, MerkleWitness, MerkleTree } from 'o1js';
import { LottoNumbers, GameBoard, ZKLottoGame } from './ZKLottoGame';

/*
Expand All @@ -8,6 +8,11 @@ import { LottoNumbers, GameBoard, ZKLottoGame } from './ZKLottoGame';
* See https://docs.minaprotocol.com/zkapps for more info.
*/

const height = 8;
const tree = new MerkleTree(height);
class MerkleWitness8 extends MerkleWitness(height) {}


let proofsEnabled = false;

describe('ZKLottoGame', () => {
Expand Down Expand Up @@ -183,13 +188,14 @@ describe('ZKLottoGame', () => {


// Claim Wins
const senderWitness = new MerkleWitness8(tree.getWitness(gameWeek.toBigInt()));

const signature2 = Signature.create(
senderKey,
[gameWeek, PlayerEntryHash]);

const txn4 = await Mina.transaction(senderAccount, async () => {
await zkApp.ClaimWinning(senderAccount, signature2, gameWeek, PlayerEntry);
await zkApp.ClaimWinning(senderAccount, signature2, gameWeek, PlayerEntry, senderWitness);
});
await txn4.prove();
await txn4.sign([senderKey]).send();
Expand Down Expand Up @@ -245,17 +251,20 @@ describe('ZKLottoGame', () => {

// Claim Wins



const wrongNumbers = [Field(2), Field(15), Field(20), Field(28), Field(35), Field(43)]
const wrongEntry = LottoNumbers.from(gameWeek, wrongNumbers);
const wrongEntryHash = wrongEntry.hash();

const senderWitness = new MerkleWitness8(tree.getWitness(gameWeek.toBigInt()));
const signature2 = Signature.create(
senderKey,
[gameWeek, wrongEntryHash]);

try {
const txn4 = await Mina.transaction(senderAccount, async () => {
await zkApp.ClaimWinning(senderAccount, signature2, gameWeek, wrongEntry);
await zkApp.ClaimWinning(senderAccount, signature2, gameWeek, wrongEntry, senderWitness);
});
await txn4.prove();
await txn4.sign([senderKey]).send();
Expand Down
63 changes: 29 additions & 34 deletions src/ZKLottoGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,6 @@ export class MerkleWitness8 extends MerkleWitness(8) {}

}

function Optional<T>(type: Provable<T>) {
return class Optional_ extends Struct({ isSome: Bool, value: type }) {
constructor(isSome: boolean | Bool, value: T) {
super({ isSome: Bool(isSome), value });
}

toFields() {
return Optional_.toFields(this);
}
};
}

class OptionalBool extends Optional(GameBoard) {}



class LottoNumbers extends Struct({
gmWeek: Field,
value: Provable.Array(Field, 6),
Expand Down Expand Up @@ -85,9 +69,7 @@ class ZKLottoGame extends SmartContract {

//Lotto Winning numbers Hash
@state(Field) LottoWinHash = State<Field>();


// @state(Field) storageTreeRoot = State<Field>();
@state(Field) storageTreeRoot = State<Field>();


init() {
Expand All @@ -98,9 +80,8 @@ class ZKLottoGame extends SmartContract {
this.currentGameTimeStart.set(UInt64.from(0));
this.currentGameTimeEnd.set(this.network.timestamp.get());
this.gameduration.set(UInt64.from(518400)); //game duration is 6 days, winning lotto numbers generated on day 7
//initiate gameRoot
// const emptyTreeRoot = new MerkleTree(8).getRoot();
// this.storageTreeRoot.set(emptyTreeRoot);
const emptyTreeRoot = new MerkleTree(8).getRoot();
this.storageTreeRoot.set(emptyTreeRoot);
}

@method async startLottoWeek() {
Expand Down Expand Up @@ -178,29 +159,43 @@ class ZKLottoGame extends SmartContract {
// const lottoEntryHash = lottoEntry.hash();
signature.verify(pubkey, [week_, lottoEntryHash]).assertTrue();

/*TO-DO
add user's lotto numbers entry to merkleTree for the Game week
*/

// retrieve the current Merkle root
const currentRoot = this.storageTreeRoot.get();
this.storageTreeRoot.requireEquals(currentRoot);

// generate a new Merkle leaf for this entry
const leaf = lottoEntryHash;

// create a Merkle Tree and update it with the new leaf
let tree = new MerkleTree(8);

let weektoBigInt: BigInt;
Provable.asProver(() => {
weektoBigInt = week_.toBigInt();
tree.setLeaf(week_.toBigInt() % BigInt(256), leaf);
});

// compute the new root and update the state
const newRoot = tree.getRoot();
this.storageTreeRoot.set(newRoot);
}

@method.returns(Bool) async ClaimWinning(
pubkey: PublicKey,
signature: Signature,
week_: Field,
winningNums: LottoNumbers,
witness: MerkleWitness8,
) {
//proof user is winner of the claim week's lotto
const winninglottoEntryHash = this.LottoWinHash.get();
this.LottoWinHash.requireEquals(this.LottoWinHash.get());
const winningLeaf = [week_].concat(winninglottoEntryHash.toFields());
signature.verify(pubkey, winningLeaf).assertTrue();
const currentRoot = this.storageTreeRoot.get();
this.storageTreeRoot.requireEquals(currentRoot);

const leaf = winningNums.hash();
const isValid = witness.calculateRoot(leaf).equals(currentRoot);
isValid.assertTrue("Invalid proof");

signature.verify(pubkey, [week_, leaf]).assertTrue();

//transfer winnings to user after successful proof verification
return Bool(true);

}
}
}

0 comments on commit 7afb7ae

Please sign in to comment.