dev-resources.site
for different kinds of informations.
Niftyzk Tutorials 5 - CosmWasm
This tutorial is the continuation of the series to explain Niftyzk for ZKP development and you should check out the previous tutorials to understand everything that’s going on here.
in Tutorials 4, we completed a Phase-2 ceremony for Groth-16 proving system, now we will continue that and export a CosmWasm contract
First, to export a cosmwasm contract, you will need a verification_key using niftyzk vkey
and the unit tests need to pass.. You don’t need to finalize the circuits to create a verifier contract from it, however you will need to reexport your contract after finalization to match the new verification key.
Usage: niftyzk gencontract [options]
Generate a cosmwasm verifier smart contract
Options:
--circuit The full name of the circuit file to use. Defaults to circuit.circom
--ark Use the Arkworks Groth-16 verifier implementation
--bellman Use the Bellman Groth-16 verifier implementation
--overwrite If a contract directory already exists, you are required use this option to overwrite
it.
--folder [name] Specify the name of the generated contract's folder
-h, --help display help for command
The niftyzk gencontract
command accepts the above arguments. You can specify the name of the circuit if your using one with a different name. The --ark
and --bellman
allows you to select a Rust library and the --folder [name]
lets you name the folder where you export the contract to. If the folder exists already, you need to explicitly overwrite it with the --overwrite
flag.
Let’s export a contract now from a compiled circuit.
$ niftyzk gencontract --ark --folder contract
Writing .cargo/config.toml
Writing Cargo.toml
Writing .gitignore
Writing src/lib.rs
Writing src/msg.rs
Writing src/contract.rs
Writing src/verify.rs
Done
You need to have rust installed. To compile the contract, the rust compiler backed must be installed: rustup target add wasm32-unknown-unknown
and then run cargo test
inside the directory, that will install the dependencies and runs the generated tests.
Build the contracts using cargo wasm
and if you have installed cosmwasm-check with cargo insall cosmwasm-check
you can verify that these are valid cosmwasm contracts cosmwasm-check ./target/wasm32-unknown-unknown/release/contract.wasm
now we verified that the contracts are correct. Let’s see what we got in the source code.
src/lib.rs
is the entry point of our contract and /src/contract.rs
contains the implementations. The zkp verification is found inside src/verify.rs
You are free to modify all code however if you change the inlined parameters your verification will fail.
To trigger the smart contract, you call the Query function with a VerifyProof
message.
For the accepted proof format see the lib/contract.rs
unit test test_verify
The proof_str
variable is a json string that is serialized directly from the snarkjs groth16.fullProve
proof , while the pub_input_str
is the stringified publicSignals variable. Using it is pretty straight forward, which is the benefit of choosing Arkworks implementation. However while easy to use, the Arkworks library is not fully audited.
See the documentation to learn more:
Bellman
The Bellman library was originally developed for ZCash by Matter Labs and we are importing the DoraFactory fork, the old version has been archived.
$ niftyzk gencontract --bellman --folder secondcontract
Writing .cargo/config.toml
Writing .gitignore
Writing Cargo.toml
Writing src/lib.rs
Writing src/msg.rs
Writing src/parser.rs
Writing src/types.rs
Writing src/verify.rs
Writing src/contract.rs
Writing lib/adapter.js
Done
We generate a new contract inside the secondcontract directory and as you can see there are more things going on. It not only created a new contract directory with the rust code, but added a lib/adapter.js
file to our lib!
The Bellman library uses uncompressed vkey and proofs which are in a different format.
Let’s see the adapter.
lib/adapter.js
/**
* The verification key adapter transforms the verification key into a format usable by the Bellman_ce based verifier
* @param {string} verification_key_string - The verification_key.json as a string
* @returns {string} uncompressed_vkey - Returns an uncompressed version of the verificaiton_key.json which can be parsed inside the rust verifier contract
*/
export async function verificationKeyAdapter(verification_key_string);
You need to adapt the verification key for use, this was done for you by the code generating process and the adapted vkey is inlined into the rust code.
/**
* The proofAdapter adapts proofs generated with snarkjs into a format parsable by a bellman verifier.
* Use this function on the front-end, to adapt proofs generated by the client for on-chain use
* @param {string} verification_key_string - The contents of the verification_key.json as a string
* @param {string} proof_string - The snarkjs generated proof as a string
* @returns {string} - Returns the adapted proof to use inside rust bellman verifier
*/
export async function proofAdapter(verification_key_string, proof_string);
The proof adapter is a function you will need to use on the client or server after you have created the proofs and want to call a smart contract with them.
If you check out the tests in src/contract.rs
you will see an example of a adapted proof string and a adapted public input string.
The bellman library is more mature and recommended to use over the arkworks implementation, you should evaluate which fits your use-case better.
You can again run cargo wasm
and use cosmwasm-check ./target/wasm32-unknown-unknown/release/contract.wasm
Once you have verified the contracts are valid they are ready for deployment.
I hope you like niftyzk and the tutorial series and keep on building!
Featured ones: