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)