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.git
To run cicuits, go inside the circuits
folder:
cd circuits
Then, follow the intructions in the README file in the circuits
folder.
To run contracts, go inside the contracts
folder:
cd contracts
Then, follow the intructions in the README file in the contracts
folder.
To run the frontend, go inside the zkgames-ui
folder:
cd zkgames-ui
Then, 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
,zkey
andverifier.sol
files using theexecute.sh
file.
2. Create the necessary smart contracts:
- Inside the
contracts/contracts
folder, 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.js
file 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/pages
to access the new game. - Create the css of that page inside
zkgames-ui/styles
, called<GameName>.module.css
. - Add an image inside
zkgames-ui/assets
to represent the game (width: 700 pixels and height: 700 pixels). - Inside
zkgames-ui/public/zkproof
add a new folder with the wasm and zkey elements generated before. - Inside
zkgames-ui/utils/abiFiles
, add a new folder with thejson
abi 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>.js
with the code to export the call data. - In
zkgames-ui/components/gameList.js
add the game as follows:
{
nameGame: "<nameGame>",
imageGame: nameGameImage,
urlGame: "/<nameGame>",
}