To begin, we need to install the required dependencies. Make sure you have Node.js and npm installed before proceeding.
First, let's install Circom:
npm install -g circom
Next, we'll generate the circuit file for our Sudoku game proof:
circom create sudoku.circom
Open the sudoku.circom
file in your preferred editor and write the following code:
template Sudoku(idx) { signal a[9][9]; signal x[10]; signal y[10]; signal v[10]; for i in [0..8] { for j in [0..8] { constraint a[i][j] > 0; constraint a[i][j] < 10; } } for i in [0..8] { for j in [0..8] { c = a[i][j]; constraint x[c] == i; constraint y[c] == j; } } for i in [0..2] { for j in [0..2] { num = i * 3 + j; constraint v[num] == (a[x[num]][y[num]]); } } def commodore = multiplexer([ private x[0], private x[1], private x[2], private x[3], private x[4], private x[5], private x[6], private x[7], private x[8] ]); def everest = multiplexer([ private y[0], private y[1], private y[2], private y[3], private y[4], private y[5], private y[6], private y[7], private y[8] ]); def kilimanjaro = multiplexer([ private v[0], private v[1], private v[2], private v[3], private v[4], private v[5], private v[6], private v[7], private v[8] ]); constant C = 1; for i in [0..2] { for j in [0..2] { constraint commodore[num] == i; constraint everest[num] == j; constraint kilimanjaro[num] == (a[commodore[num]][everest[num]]); } } } component main = Sudoku(0);
Now, let's generate the circuit:
circom sudoku.circom
This will create a circuit.json
file that represents our Sudoku game proof circuit.
Next, we'll write the Solidity smart contract. In the contracts
directory, create a new file called Sudoku.sol
and add the following code:
pragma solidity ^0.8.0; contract Sudoku { struct Puzzle { uint8[9][9] puzzle; } struct Proof { uint32[9][9] proof; } function verifySolution(Puzzle memory puzzle, Proof memory proof) public pure returns (bool) { // TODO: Implement the verification logic return false; } }
The verifySolution
function takes in a Puzzle
struct (represents the Sudoku puzzle) and a Proof
struct (represents the proof provided by the user) and returns a boolean indicating whether the solution is valid or not. We'll fill in the verification logic later.
Finally, let's write the JavaScript frontend code. In the src
directory, create a new file called app.js
and add the following code:
const Web3 = require('web3'); const contractData = require('../build/contracts/Sudoku.json'); const web3 = new Web3('http://localhost:8545'); // Update with your Ethereum provider's URL const contractAddress = '<YOUR_CONTRACT_ADDRESS>'; // Update with the deployed contract address const accountAddress = '<YOUR_ACCOUNT_ADDRESS>'; // Update with your Ethereum account address const contract = new web3.eth.Contract(contractData.abi, contractAddress); async function verifySolution(puzzle, proof) { const result = await contract.methods.verifySolution(puzzle, proof).call({ from: accountAddress }); return result; } async function run() { const puzzle = [ [6, 0, 2, 0, 0, 0, 0, 0, 0], [0, 0, 0, 7, 5, 2, 6, 0, 0], [0, 0, 8, 0, 6, 0, 0, 0, 0], [0, 0, 4, 0, 9, 8, 0, 7, 0], [7, 6, 0, 0, 0, 0, 0, 2, 4], [0, 3, 0, 5, 7, 0, 9, 0, 0], [0, 0, 0, 0, 1, 0, 4, 0, 0], [0, 0, 9, 3, 2, 7, 0, 0, 0], [0, 0, 0, 0, 0, 0, 6, 0, 5], ]; const proof = [ [0, 6, 7, 5, 4, 2, 3, 8, 9], [3, 1, 5, 0, 0, 0, 7, 6, 4], [2, 4, 8, 6, 9, 3, 1, 5, 0], [1, 7, 0, 4, 2, 6, 8, 9, 3], [9, 5, 6, 0, 8, 1, 2, 0, 7], [8, 2, 3, 7, 0, 5, 0, 4, 0], [5, 9, 2, 8, 0, 0, 0, 7, 6], [6, 8, 1, 9, 3, 0, 4, 2, 5], [4, 3, 0, 0, 0, 0, 0, 0, 0], ]; const result = await verifySolution(puzzle, proof); console.log(result); } run();
This code sets up the Web3 provider, loads the Sudoku smart contract, and provides a sample Sudoku puzzle and proof to test the verification.
Before running the script, make sure to replace <YOUR_CONTRACT_ADDRESS>
with the deployed smart contract address and <YOUR_ACCOUNT_ADDRESS>
with your Ethereum account address.
To run the application, open a terminal window and navigate to the project directory. Then, run the following command:
node src/app.js
This will execute the script and print the result indicating whether the solution is valid or not.
That's it! You have created a zk DApp using Circom, Solidity, and JavaScript to prove someone's ability to solve a Sudoku game without revealing the answer. Feel free to enhance and customize the code as per your requirements.
Ps. This content is AI-generated by the prompt:
We will create a zk DApp to prove that someone knows how to solve a sudoku game, without revealing the answer. We will use Circom (for circuits), Solidity (for smart contracts) and Javascript (for the frontend).
Top comments (0)