Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added smart contract interaction on player submitting commitments #14

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
wip
jimmychu0807 committed Sep 10, 2024
commit a37ebc0c16a3e2f27aa63e28c549248bc1f7de7d
37 changes: 15 additions & 22 deletions apps/contracts/contracts/GuessingGame.sol
Original file line number Diff line number Diff line change
@@ -3,15 +3,22 @@ pragma solidity ^0.8.23;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IGuessingGame} from "./interfaces/IGuessingGame.sol";
import {ISubmitRangeCheckVerifier} from "./interfaces/ISubmitRangeCheckVerifier.sol";
import {MIN_NUM, MAX_NUM, ROUND_TO_WIN} from "./base/Constants.sol";

contract GuessingGame is IGuessingGame, Ownable {

ISubmitRangeCheckVerifier public submitRangeCheckVerifier;

// Storing all the game info. Refer to the interface to see the game struct
Game[] public games;
uint32 public nextGameId = 0;

// Constructor
constructor() Ownable(msg.sender) {
// @param srAddr: submit-rangecheck verifier address
constructor(ISubmitRangeCheckVerifier srAddr) Ownable(msg.sender) {
// Initialization happens here
submitRangeCheckVerifier = srAddr;
}

// Modifiers declaration
@@ -94,24 +101,6 @@ contract GuessingGame is IGuessingGame, Ownable {
return game.players[0];
}

/**
* Helpers functions
**/

function _verifyBidProof(
bytes32 proof,
uint8 bid,
uint256 nullifier
) internal pure returns (bool) {
/**
* TODO: verify proof
**/
proof;
bid;
nullifier;
return true;
}

function _updateGameState(
uint32 gameId,
GameState state
@@ -195,8 +184,8 @@ contract GuessingGame is IGuessingGame, Ownable {

function submitCommitment(
uint32 gameId,
bytes32 bid_null_commitment,
bytes32 null_commitment
uint256[24] calldata proof,
uint256[2] calldata pubSignals
)
external
override
@@ -207,7 +196,11 @@ contract GuessingGame is IGuessingGame, Ownable {
// each player submit a bid. The last player that submit a bid will change the game state
Game storage game = games[gameId];
uint8 round = game.currentRound;
game.bids[round][msg.sender] = Bid(bid_null_commitment, null_commitment);

// Verify the computation and proof
submitRangeCheckVerifier.verifyProof()

game.bids[round][msg.sender] = Bid(pubSignals[0], pubSignals[1]);
emit BidSubmitted(gameId, round, msg.sender);

// If all players have submitted bid, update game state
4 changes: 2 additions & 2 deletions apps/contracts/contracts/interfaces/IGuessingGame.sol
Original file line number Diff line number Diff line change
@@ -3,8 +3,8 @@ pragma solidity ^0.8.23;

interface IGuessingGame {
struct Bid {
bytes32 bid_null_commitment;
bytes32 null_commitment;
uint256 submission;
uint256 nullifier;
}

struct Game {
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

interface ISubmitRangeCheckVerifier {
function verifyProof(
uint256[24] calldata _proof,
uint256[2] calldata _pubSignals
) external view returns (bool);
}
4 changes: 2 additions & 2 deletions apps/contracts/tasks/deploy.ts
Original file line number Diff line number Diff line change
@@ -3,9 +3,9 @@ import { task, types } from "hardhat/config";
task("deploy", "Deploy a contract")
.addOptionalParam("logs", "Print the logs", true, types.boolean)
.setAction(async ({ logs }, { ethers, run }) => {
const game = await run("deploy:game", { logs });
const gameContract = await run("deploy:game", { logs });
const verifiers = await run("deploy:verifiers", { logs });
return { game, ...verifiers };
return { gameContract, ...verifiers };
});

task("deploy:game", "Deploy a GuessingGame contract")
30 changes: 24 additions & 6 deletions apps/contracts/test/GuessingGame.ts
Original file line number Diff line number Diff line change
@@ -26,16 +26,26 @@ describe("GuessingGame", () => {

async function deployContractsGameStarted() {
contracts = await run("deploy", { logs: false });
[host, bob, charlie] = await hre.ethers.getSigners();
[host, bob, charlie, dave] = await hre.ethers.getSigners();
Object.values(contracts).map((c) => c.connect(host));

return { contracts, players: { host, bob, charlie } };
const { gameContract } = contracts;

const GAME_ID = 0;
await gameContract.newGame();
await Promise.all([
gameContract.connect(bob).joinGame(GAME_ID),
gameContract.connect(charlie).joinGame(GAME_ID),
]);
await gameContract.startGame(GAME_ID);

return { contracts, players: { host, bob, charlie, dave } };
}

describe("L New Game", () => {
it("should create a new game", async () => {
const { contracts, players } = await loadFixture(deployContractsCleanSlate);
const { game: gameContract } = contracts;
const { gameContract } = contracts;
const { host } = players;

await gameContract.newGame();
@@ -50,7 +60,7 @@ describe("GuessingGame", () => {

it("host can't join the game again, but other players can", async () => {
const { contracts, players } = await loadFixture(deployContractsCleanSlate);
const { game: gameContract } = contracts;
const { gameContract } = contracts;
const { host, bob } = players;

await gameContract.newGame();
@@ -71,7 +81,7 @@ describe("GuessingGame", () => {

it("can start game by host once there are more than two players", async () => {
const { contracts, players } = await loadFixture(deployContractsCleanSlate);
const { game: gameContract } = contracts;
const { gameContract } = contracts;
const { host, bob, charlie } = players;

await gameContract.newGame();
@@ -93,7 +103,15 @@ describe("GuessingGame", () => {
});
});

describe("L Players submitting and revealing bid for a round", () => {});
describe("L After a game started", () => {
it("players can submit a commitment", async () => {
const { contracts, players } = await loadFixture(deployContractsGameStarted);
const { gameContract } = contracts;
const { host, bob, charlie } = players;


});
});

describe("L Range check: genarate proof offchain, verify proof onchain", () => {
it("should create a range proof and be verified", async () => {