This repository is an example of how zK-Snarks can be combined with the concept of Soul Bound Token.
This follows part 3 of Spartan Labs Soul Bound Token Article series:
- Part 1: The ABCs of SBT
- Part 2: Implementations of SBT
- Part 3: zkSBT
For demo purposes of the toy example, we have included the next.js folder over at client/
For the server, we have included the express server over at server/
To run the application, just run npm install
and then npm run dev
in both the client/
and npm start
for the server/
folders.
To generate the following contract by yourself, you can refer to the instructions below:
Clone this repository
git clone https://github.com/SpartanLabsXyz/zk-sbt.git
yarn
to install dependencies
Install Circom 2 from https://github.com/iden3/circom
- node : 16.16
- snarkjs: 0.4.25
- circom v2: 2.0.3
client/
: contains demo code where we can run our prover
server/
: contains the endpoints for proof generation and call data generation
contracts/
: contains Verifier.sol
which allows us to prove attributes about SBT
contracts/Verifier.sol
- This file is autogenerated by snarkjs.
- For our zkSBT contract, we would be using Verifier.sol for proving that a given SBT has valid attributes using
verifyProof
. verifyProof
is a function that takes in a calldata and a proof and returns a boolean.
yarn circom:dev
to build deterministic development circuits.
Further, for debugging purposes, you may wish to inspect the intermediate files. This is possible with the --debug
flag which the circom:dev
task enables by default. You'll find them (by default) in artifacts/circom/
To build a single circuit during development, you can use the --circuit
CLI parameter. For example, if you make a change to hash.circom
and you want to only rebuild that, you can run yarn circom:dev --circuit hash
.
yarn circom:prod
for production builds (using Date.now()
as entropy)
Run sh execute.sh
for the step by step setup
For more information on setting up, visit Their README
npm -i # installs all dependencies
Run app/index.html
The script for proving is in app/index.js
circom circuit.circom --r1cs --wasm --sym
Options:
--r1cs
: generates circuit.r1cs (the r1cs constraint system of the circuit in binary format).
--wasm
: generates circuit.wasm (the wasm code to generate the witness – more on that later).
--sym
: generates circuit.sym (a symbols file required for debugging and printing the constraint system in an annotated mode).
-
look at some of the information circuit.r1cs :
snarkjs info -r circuit.r1cs
-
print constraints:
snarkjs printconstraints -r circuit.r1cs -s circuit.sym
you can ignore the 1main prefix and just read this as:
(-a) * b - (-c) = 0
Which, if you rearrange the equation, is the same as a * b = c.
The need for a trusted setup boils down to the fact that the balance between privacy for the prover, and assurance of not cheating for the verifier, is delicate.
snarkjs setup -r circuit.r1cs
: This will generate both a proving and a verification key in the form of two files: proving_key.json and verification_key.json.
- Compile contracts
- Deploy and verify
A Zero Knowledge Soul Bound token project using starter developed by Blaine & Brian:
- using Hardhat
- hardhat-circom.
This combines the multiple steps of the Circom and SnarkJS workflow into your Hardhat workflow.
By providing configuration containing your Phase 1 Powers of Tau and circuits, this plugin will:
- Compile the circuits
- Apply the final beacon
- Output your
wasm
andzkey
files - Generate and output a
Verifier.sol