In this tutorial, we will create a circuit, compile it and then deploy our ceremony server on a VPS to accept anonymous contributions. After this we will finalize the circuit and export the final Verification key
Let’s run niftyzk init projectname
to create a new project
Creating a new directory with name projectname
? What project do you want to scaffold? Commit-Reveal Scheme
? Choose the hashing algorithm to use: poseidon
? Do you wish to add tamperproof public inputs? (E.g: walletaddress): no
Generating circuits
Generating javascript
Done
Run npm install in your project folder
So run npm install
and let’s download the ptau files
niftyzk ptaufiles
, we are going to grab a smaller file for our commit-reveal scheme
? Select a ptau file to download powersOfTau28_hez_final_14.ptau
Connecting to download powersOfTau28_hez_final_14.ptau
Starting to download 18.08 MiB
downloading [====================] 100% 0.0s
Now just run niftyzk compile
and select the ptau file, so far so good.
Now run git init
and do a git add .
If you check git status
You should see:
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: circuits/circuit.circom
new file: circuits/commitment_hasher.circom
new file: circuits/compiled/circuit.r1cs
new file: circuits/compiled/circuit.sym
new file: circuits/compiled/circuit_js/circuit.wasm
new file: circuits/compiled/circuit_js/generate_witness.js
new file: circuits/compiled/circuit_js/witness_calculator.js
new file: circuits/compiled/zkeys/circuit_0000.zkey
new file: lib/index.js
new file: package-lock.json
new file: package.json
new file: readme.md
new file: test/index.test.js
new file: test/input.js
These are the files that were created during the scaffold and compilation. You can see the circuits/compiled
directory contains all the artifacts outputted by the compiler and there is the zkey which will be used for contributions during the ceremony. The ptau files are not commited due to their size but you can always just download them again.
Let’s commit the files
$ git commit -m "initial commit"
[master (root-commit) 946c8e7] initial commit
15 files changed, 7212 insertions(+)
create mode 100644 .gitignore
create mode 100644 circuits/circuit.circom
create mode 100644 circuits/commitment_hasher.circom
create mode 100644 circuits/compiled/circuit.r1cs
create mode 100644 circuits/compiled/circuit.sym
create mode 100644 circuits/compiled/circuit_js/circuit.wasm
create mode 100644 circuits/compiled/circuit_js/generate_witness.js
create mode 100644 circuits/compiled/circuit_js/witness_calculator.js
create mode 100644 circuits/compiled/zkeys/circuit_0000.zkey
create mode 100644 lib/index.js
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 readme.md
create mode 100644 test/index.test.js
create mode 100644 test/input.js
Go over to your favorite git hosting solution, I’m using github but you can use whatever you want and push the repository. We will clone it to a VPS later, but you can also copy the whole directory there manually, that’s up to you.
The repository is here for reference:
https://github.com/NiftyZk/projectname
Manual Deployment
For the VPS, I’m creating a Hetzner server. You can use any hosting solution, or even self-host on a raspberry pi. You will need SSH to log in. We will configure Nginx and even configure a domain using namecheap.
On console.hetzner.cloud I created a 2VCPU, 4 GB Ram X86 VPS for €4.11/month running Ubuntu, and configured it with my SSH keys. If you are new to SSH you should invest some time to learn about it.
ssh root@serverip
So I’m connecting to the remote VPS I created with the SSH client, I’m connecting as root as there are no other users configured. You can configure that for yourself, it’s out of scope for now for showcasing the ceremony.
sudo apt update
sudo apt upgrade
sudo apt install nginx
We install snap for certbot
sudo apt install snapd
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx
You should configure your domain to have an A record with host @
pointing to the IP of your VPS for certbot to issue the certificate. Your DNS changes will take time to propagate but if you did everything well, the IP address should already show NGINX is running.
Next we are going to install nodejs using the official docs
https://nodejs.org/en/download
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
This installs nvm and you might need to restart the ssh session after installation. Install a new node version using nvm
nvm install 22
We are going to install pm2, this will help keep the ceremony server open when the ssh session is closed.
npm install -g pm2
pm2 startup systemd
Clone the repository we created earlier using Git to your home directory and don’t forget to install niftyzk
npm install -g git+https://github.com/NiftyZk/niftyzk.git
Next step is to configure nginx to proxy the port 3000 to 443 SSL and upgrade all non-SSL connections to use it.You need to copy this file to /etc/nginx/sites-available/default
and make sure to edit YOURDOMAIN parts to use your configured domain name!
server {
#SSL only
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
client_max_body_size 200M;
ssl_certificate /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/YOURDOMAIN/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
server_name YOURDOMAIN;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection ‘upgrade’;
proxy_pass http://127.0.0.1:3000; #port where you are serving your express app.
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_pass_header Server;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
Then after editing the file, reload nginx
sudo systemctl reload nginx
Now, we are going to create a shell script to execute niftyzk ceremony, that can be ran by pm2
cd into your cloned project’s directory and npm install
then touch run.sh
and open it with an editor.
#!/usr/bin/bash
niftyzk ceremony
Download the used ptau file with niftyzk ptaufiles
, we used the 14th for compiling, you must select the same.To finally run the ceremony, pm2 start run.sh
Congrats, you got the ceremony server running on your domain.When you visit it you should see this:
How does it work?
Anyone can visit your ceremony, the participation is public. They enter a name and then they are placed in a queue. When it’s their turn to contribute, they will be prompted to enter some entropy and on the client side they run SnarkJS to make a contribution to the last zkey.
The participation in the ceremony can be verified by downloading the log file and comparing the entries in the log file with the sha256 hash of your name.
A directory have been added to your repository called contributions, that contains the log.csv file.
So let’s enter the name: helloworld
and add some random entropy.What happened? A contribution was added to the /circuits/compiled/zkeys/
directory called circuit_0001.zkey
and the log file has a csv entry added
Contribution,936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af,087ec9f31cc05fa8db3c46ed360a5294fd6c99aaa97e244044ca936c3e302e35cd34080e86eaa4a67d1e2c717d25b90759f46cb4af692ac5b3e2d17f04bacbfa,circuit_0001.zkey
The first hash is a sha256 hash of the name entered, the second is the blake2b hash of the circuit which will be later logged on circuit finalization.
echo -n helloworld | sha256sum
936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af -
The ceremony can be online indefinitely and as long as one of the contributors don’t cheat, it’s secure. The largest PTAU file the ceremony server supports can be logged with niftyzk ptaufiles
powersOfTau28_hez_final_15.ptau blake2b hash: 982372c867d229c236091f767e703253249a9b432c1710b4f326306bfa2428a17b06240359606cfe4d580b10a5a1f63fbed499527069c18ae17060472969ae6e Power: 15, Max Constraints: 32K Size: 36.08 MiB Supports built in ceremony server: YES
The reason for this is the networking bottleneck. Any circuits that require more than max 32k constraints will need to do a ceremony manually using snarkjs.
So after a few contributions, you can take down the server. For testing now we can add contributions manually.
Then do a git add .
root@niftyzk-ceremony:/home/nifty/projectname# git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: circuits/compiled/contributions/log.csv
new file: circuits/compiled/zkeys/circuit_0001.zkey
new file: circuits/compiled/zkeys/circuit_0002.zkey
new file: circuits/compiled/zkeys/circuit_0003.zkey
new file: run.sh
And commit these zkeys and push to your repository.You can turn off your webserver now.
Finalize the circuit
You can finalize the ceremony locally, just pull the changes and select a random beacon to use.
niftyzk finalize --beacon 0000000000000000000102b8a74a6e9b9344f0abb3ba25dea7f847c7296fb21d
Niftyzk finalize will complete the ceremony, I used a bitcoin block hash for a beacon. It should be a verifiable hexadecimal number.
When the finalization finished, you should see the contributions are logged.It will be always verifiable that your contribution is in the final zkey as long as you know the name you entered.
[INFO] niftyzk: contribution #1 936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af:
087ec9f3 1cc05fa8 db3c46ed 360a5294
fd6c99aa a97e2440 44ca936c 3e302e35
cd34080e 86eaa4a6 7d1e2c71 7d25b907
59f46cb4 af692ac5 b3e2d17f 04bacbfa
[INFO] niftyzk: ZKey Ok!
This creates the circuit.final.zkey
Now you can run niftyzk vkey --final
and create the final verification_key.json
now your circuit is secure and ready for production.
Top comments (0)