ZKP’s are a promising rapidly developing technology and are soon going to be a critical part of many of our security protocols.
In this article we are going to get hands on with libsnarks, truffle and docker.
Before we do anything — let’s make sure we have all the required programs we’ll need to run our app. If you have issues running the below block — please install the missing dep before following along.
docker -v # Docker version 18.09.1, build 4c52b90git --version # git version 2.17.2 (Apple Git-113)node -v # v10.15.0truffle version # Truffle v5.0.4 (core: 5.0.4)python3 --version # Python 3.7.2
Also for debugging purposes we will deploy the code to a locally running blockchain: Please download Ganache as well
Truffle Suite | Ganache_The Truffle suite of tools make dapp development easier and more consistent._truffleframework.com
Now we just need to finish up by installing the python packages needed to run our app. The application is just some wrapped up calls to ZoKrates and the Blockchain.
pip3 install docker flask web3
First we need to get the some repos.
git clone
We now have the ZoKrates docker container build — this is a high level library that allows us to interact with libsnark via simple command line commands.
If you’d like, you can access the ZoKrates
binary by starting an interactive session with the docker container
*optional*
docker run -v $PWD/code:/home/zokrates/ZoKrates/target/debug/code -ti zokrates_tutorial /bin/bash
Awesome — if you want to learn about ZoKrates before we move on check out their docs here — https://zokrates.github.io/
We’ll get back to this container shortly, next we need to setup our Blockchain environment and get some ZKP application code.
In order for us to create an environment suited for a public ledger of truth, where we can use a smart contract to execute the verifications, and commit our verification results to the network we need to connect to a blockchain.
Since we don’t want to spend any money for this POC, we’ll just use Ganache to start a tiny ETH network locally. This way we can restart the chain as needed and use the Ganache GUI to explore our tx’s.
We’ve made it this far, and we now have locally running network and docker container ready to compile ZKP proofs into smart contracts.
Here would be a good starting point for anyone who wants to deploy custom ZKP verification smart contracts for their use case. However please follow along for a simple example on how to create a simple ZKP auth system.
git clone https://github.com/drbh/zksnark-app-demo.gitcd zksnark-app-demo/
In this repo we have a few files that we’ll use for out application
inside of code/
we have two folders preimage
and get_hashes
which represent two different libsnark circuits. These are basically programs written in a special form, that snarks can create proofs for.
Along with the demo code, i’ve left an example verification.key
and proving.key
and other artifacts from running the setup. These are for convenience and you should not use these keys aside from following this demo.
REPEAT — DO NOT USE THESE KEYS FOR ANY PRODUCTION SYSTEM. GENERATE YOUR OWN KEYS!
However for the ease of running this demo — i’ve provided these keys so the matching Smart Contract contains the keys needed to run the demo out of the box.
import "hashes/sha256/512bitPacked.code" as sha256packed
def main(private field a, private field b, private field c, private field d, field h0Pub, field h1Pub) -> (field[2]):h = sha256packed([a, b, c, d])h[0] == h0Pubh[1] == h1Pubreturn h
inside of contracts
we have Verifier.sol
which is a precompiled version of our code above — just compiled into a smart contract written in solidity. This file has the verification.key
embedded into the contract.
Getting the app running is simple,
Make sure we have a fresh start of Ganache running and no Tx’s have been committed. Just click restart in settings in the top right if you need a fresh chain.
Fresh start of Ganache
Next we’ll start the server
python3 app.py
Server started
Great! let’s test out server. We can open up any REST client like Postman or Insomnia.
Request to compile and migrate
This request will take a few seconds ~5 or so, and you should see the console print the truffle deployment logs. below
Truffle logs
Also looking at the Ganache console, we can see 4 transactions — which were generated by the truffle migrate
command, called with out deploy request.
Yay, we’ve deployed the verifier to chain
Now we can test our abilities to create a hash from a preimage — the exact data we will be proving in our proof.
curl --request POST \--url http://127.0.0.1:5000/witness \--header 'content-type: application/json' \--data '{"input": "123"}'
…or in a more visually pleasing format below
Compute a witness — get hash
Cool, we get a witness data back — the info we are interested in are our original input, and the returned digest.
Now using the data from our witness, we can build a proof! We’ll pass the server all the information needed to rebuild the witness and generate a proof for that witness. We get back a proof in JSON form.
Build a proof from the hash and preimage
The proof we’ve created is a secret and as “valuable” as the preimage itself. Essentially knowing this proof, and knowing the original secret are equivalent ways to convince a 3rd party that you know the secret.
Now that we have a proof, let’s use it. We can make a call to the smart contract code, and run this off of chain on the local machine. This way we don’t have to make any commit to chain but we can trust that we are running the proof against trusted source code.
off-chain contract call
In order to make this assertion of proof public and immutable, we need to make a transaction to the chain by running the smart contract on chain with the proof as the input.
on-chain contract transaction!
We can see in raw logs and transaction logs have received a new transaction.
The log indicates a new Tx hash hash been added to the chain at 0x9e08f4656e529da61fc45de7cb77668709604fe82f66de12989aee79fe1112db
and we can now prove to all nodes in the chain that we know the pre image to the hash 0x5a00b6425adf76d719eeafd1c522be1a4b0267620e08c32fa79aec4a8a684481
which we know (since it was the example in the demo) is 123.
Added new Tx to chain as output of Smart Contract
So we’ve gone full circle with ZKPs. We’ve created a witness, a proof, and then verified that on chain. A third party observer can trust that I know the pre image to a hash as long as they trust the initial setup and the legitimacy of the chain.
There are many use cases where knowing the truth without revealing the truth is important. These tools are making applications and processes like this possible.
Check out Ganache, and ZoKrates for more information. Also checkout Bellman ( a newer library for ZKSNARKS ). Maybe Snarks isn’t the best solution for your usecase and antother protocol like Bulletproofs, or Starks better fits your needs. There are alot of development out there for ZKPs and are rapidly changing so if your interested in ZKP’s, your journey has just begun.
For a list of resources check out another article I wrote: https://medium.com/@david.richard.holtz/zkps-for-dummies-7242e7fcaad4
Thanks for getting through this adventure with me. Please show support and 👏 (clap) for this article.
Remember you can clap up to 50 times, and clapping for this article would be really helpful in the Medium algorithm.
Any support is greatly appreciated ❤️
Also, please answer the questions and add to the discussion below