Prove, verify, and check deployability
This tutorial takes a registered circuit through the full developer loop: build a witness, generate
a proof, verify it, wrap it in the canonical envelope, and finally ask whether the verifier could be
deployed on a given chain. It uses the zerostyl-sdk crate and the zerostyl-orbit CLI.
You'll use: zerostyl-sdk, zerostyl-prove, zerostyl-orbit. Time: ~15 minutes.
This tutorial runs from a clone of the repository: it uses the zerostyl-prove CLI (built from
source) and the zk_private_demo worked example at examples/zk_private_demo/. The zerostyl-sdk
crate itself is published on crates.io.
1. Build a witness
WitnessBuilder assembles the JSON a circuit descriptor expects (decimal or 0x-hex strings,
arrays for Merkle paths), with optional schema checking:
use zerostyl_sdk::{WitnessBuilder, ZeroStyl};
let witness = WitnessBuilder::new()
.set_u64("collateral", 500_000)
.set_u64("collateral_nonce", 42)
.set_u64("threshold", 100_000)
.build();
2. Register the circuit and mock-prove first
mock_prove runs the constraint system without generating a real proof — instant, and the fastest
way to catch a bad witness before paying for keygen:
let mut client = ZeroStyl::new()?; // default cache dir
client.register(zk_private_demo::descriptor())?;
let circuit = client.circuit("deposit")?;
let report = circuit.mock_prove(&witness)?;
assert!(report.satisfied, "constraints unsatisfied: {:?}", report.failures);
If constraints fail, jump to Debug a failing witness before proving.
3. Prove and verify
let artifact = circuit.prove(&witness)?; // real halo2 KZG proof
assert!(circuit.verify(&artifact.bytes, &artifact.public_inputs_json)?);
ProofArtifact carries the raw proof bytes and the public_inputs_json (the 32-byte
little-endian field representations the verifier consumes).
The same thing from the CLI
zerostyl-prove generate --circuit state_mask --witnesses witness.json --output proof.bin
zerostyl-prove verify --circuit state_mask --proof proof.bin --inputs public_inputs.json
ZeroStyl Prover — circuit: state_mask k: 10
Proof: 2720 bytes → proof.bin
Public inputs → public_inputs.json
Done.
ZeroStyl Verifier — circuit: state_mask k: 10
Proof is VALID
Done.
4. Seal the proof for transport
The canonical envelope stamps the proof with the circuit id so a reader can tell which circuit it belongs to before verifying. It is for off-chain storage/transport — on-chain verifiers expect the raw bytes:
let sealed = circuit.seal(&artifact); // magic + circuit id + version + proof
let raw = circuit.open(&sealed)?; // rejects a proof sealed for another circuit
assert_eq!(raw, artifact.bytes);
5. Check deployability per chain
A real verifier for this proof is large. Before you plan a deployment, ask zerostyl-orbit whether
it fits a chain — and whether that chain has the precompiles on-chain verification needs:
zerostyl-orbit matrix --wasm zerostyl_verifier.wasm --proving-system halo2_kzg
Artifact: 91.1 KB compressed / 338.3 KB decompressed
arbitrum-sepolia: NOT deployable
[OVER] compressed (on-chain code): 91.1 KB / 24.0 KB (67.1 KB over)
[OVER] decompressed WASM: 338.3 KB / 256.0 KB (82.3 KB over)
arbitrum-sepolia: Halo2Kzg on-chain verification precompiles available
[ok ] 0x06 ecAdd (bn256)
[ok ] 0x07 ecMul (bn256)
[ok ] 0x08 ecPairing (bn256)
This quantifies the honest state of the toolkit: the BN254 pairing precompile a KZG verifier needs is available, but the verifier is ~4× over the 24 KB compressed limit — so on-chain verification is a size problem, not a precompile problem. A small contract, by contrast, passes:
arbitrum-sepolia: DEPLOYABLE
[ok ] compressed (on-chain code): 12.0 KB / 24.0 KB (12.0 KB headroom)
[ok ] decompressed WASM: 40.0 KB / 256.0 KB (216.0 KB headroom)
Scaffold a custom Orbit chain profile (with the caps raised to the 96 KB / 256 KB maximums) with
zerostyl-orbit init --output my-chain.toml, then pass --chain my-chain.toml.
Next steps
- Understand the event a contract emits on an accepted proof → Events & Fingerprinting.
- Generate the circuit and contract from annotations → #[zk_private] → circuit + contract.