zkGames is a platform that allows users to play zk (zero knowledge) games and mint an NFT as proof that they have won.
The project is currently on Harmony Mainnet and the frontend is hosted on Vercel.
zkGames has 3 games so far: Futoshiki, Skyscrapers and Sudoku.
zkGames Link:
zkGames Demo Video:
- Project Structure
- Zero Knowledge Structure
- Run Locally
- Steps to Add a New Game
- Some Images of the zkGames Application
The project has three main folders:
- circuits
- contracts
- zkgames-ui
The circuits folder contains all the circuits used in zkGames.
To learn more about the zkGames circuits, read the README file inside the circuits folder.
The contracts folder contains all the smart contracts used in zkGames.
To learn more about the zkGames smart contracts, read the README file inside the contracts folder.
The zkgames-ui folder contains the zkGames frontend.
To learn more about the zkGames frontend, read the README file in the zkgames-ui folder.
The following graphic shows the structure of the most important zero knowledge elements of the zkGames project.
├── circuits
│ ├── futoshiki
│ │ ├── futoshiki.circom
│ ├── skyscrapers
│ │ ├── skyscrapers.circom
│ ├── sudoku
│ │ ├── sudoku.circom
├── contracts
│ ├── contracts
│ │ ├── Futoshiki
│ │ │ ├── Futoshiki.sol
│ │ │ ├── verifier.sol
│ │ ├── Skyscrapers
│ │ │ ├── Skyscrapers.sol
│ │ │ ├── verifier.sol
│ │ ├── Sudoku
│ │ │ ├── Sudoku.sol
│ │ │ ├── verifier.sol
├── zkgames-ui
│ ├── public
│ │ ├── zkproof
│ │ │ ├── futoshiki
│ │ │ │ ├── futoshiki.wasm
│ │ │ │ ├── futoshiki_0001.zkey
│ │ │ ├── skyscrapers
│ │ │ │ ├── skyscrapers.wasm
│ │ │ │ ├── skyscrapers_0001.zkey
│ │ │ ├── sudoku
│ │ │ │ ├── sudoku.wasm
│ │ │ │ ├── sudoku_0001.zkey
│ ├── zkproof
│ │ ├── futoshiki
│ │ │ ├── snarkjsFutoshiki.js
│ │ ├── skyscrapers
│ │ │ ├── snarkjsSkyscrapers.js
│ │ ├── sudoku
│ │ │ ├── snarkjsSudoku.js
│ │ ├── snarkjsZkproof.js
git clone https://github.com/vplasencia/zkGames.gitTo run cicuits, go inside the circuits folder:
cd circuitsThen, follow the intructions in the README file in the circuits folder.
To run contracts, go inside the contracts folder:
cd contractsThen, follow the intructions in the README file in the contracts folder.
To run the frontend, go inside the zkgames-ui folder:
cd zkgames-uiThen, follow the intructions in the README file in the zkgames-ui folder.
Steps to follow to add a new game (in each step you can check how is done with the other games):
1. Create the required circom circuits:
- Inside the circuits folder, create a new folder and inside the new folder, create the necessary circom circuits.
- Compile the circuit and generate the
wasm,zkeyandverifier.solfiles using theexecute.shfile.
2. Create the necessary smart contracts:
- Inside the
contracts/contractsfolder, create a new folder with the necessary smart contracts. Add here the verifier.sol generated before using snarkjs. - Change the solidity version to
^0.8.4(it is the version used in the other smart contracts) and the contract name (to<gameName>Verifier) inverifier.sol. - Test the functionalities of the new smart contracts in
scripts/run.js. - Update the
contracts/scripts/deploy.jsfile and deploy smart contracts.
3. Create the user interface of the game:
- Inside
zkgames-ui/components, add a new folder to create all the components needed to render the game. - Add a new page inside
zkgames-ui/pagesto access the new game. - Create the css of that page inside
zkgames-ui/styles, called<GameName>.module.css. - Add an image inside
zkgames-ui/assetsto represent the game (width: 700 pixels and height: 700 pixels). - Inside
zkgames-ui/public/zkproofadd a new folder with the wasm and zkey elements generated before. - Inside
zkgames-ui/utils/abiFiles, add a new folder with thejsonabi file of the smart contract. - In
zkgames-ui/utils/contractaddress.json, add the new contract address. - In
zkgames-ui/zkproof, create a new folder and inside the new folder create a new file calledsnarkjs<NewGame>.jswith the code to export the call data. - In
zkgames-ui/components/gameList.jsadd the game as follows:
{
nameGame: "<nameGame>",
imageGame: nameGameImage,
urlGame: "/<nameGame>",
}



