On-Chain ZK Verification
When you make a private transaction on Orbinum, the network needs to verify that your zero-knowledge proof is mathematically valid — without learning anything about the private details it contains. To do this, each circuit has a verification key (VK): a small public artifact derived from the trusted setup that makes verification possible.
In most ZK systems, this key is hardcoded into the software. Orbinum takes a different approach: every VK is stored in the blockchain's own state, versioned and governable, just like any other on-chain data.
Why store verification keys on-chain?
When a circuit is improved — better performance, bug fix, or new trusted setup — the new VK can be registered and activated on-chain without a runtime upgrade or hard fork.
Each circuit keeps a registry of all registered versions. An upgrade registers a new version without removing the old one, allowing a transition period where both remain valid.
Every registration, activation, and removal is recorded on-chain as an event. Anyone can inspect which VK was used to verify a specific proof at any block height.
Key management requires root authorization (sudo in testnet, governance in mainnet). No single developer can silently swap a verification key.
What is an "active version"?
Each circuit has one active version at any point in time. When a private transaction is submitted, the shielded pool automatically uses the active version's VK to verify the proof.
Think of it like a pointer: other versions remain registered and accessible, but the active version is what normal transactions run against.
Old versions are not automatically deleted. They can be queried directly and removed later through an explicit governance action.
Commitments are never invalidated
This is important to understand when thinking about upgrades.
Private funds exist as commitments in the Merkle tree. That tree is never modified by a VK upgrade. A commitment created at block 500 is as valid at block 5,000,000 as when it was inserted.
A ZK proof is cryptographically tied to the proving key used to generate it. Each note records the circuit version it was created under, and the pallet verifies against that version's VK — not merely the active one. Activating a new VK does not invalidate existing notes.
This is the key property of per-note versioning: activating a new version breaks nothing. A note created under v1 stays spendable with the v1 proving key after v2 goes active. There is no migration step and no window in which funds are stuck.
A version stops being accepted only when governance explicitly retires it with retire_version.
That is the moment to coordinate — not activation.
The upgrade path
When a new circuit version is ready, the process follows a defined sequence that ensures there is no gap in service:
Switching the active version (step 5) is safe — notes created under version n keep verifying against version n.
Retiring version n (step 7) is what makes those proofs stop working. Give holders enough time to
spend or roll over notes created under it, and prefer retire_version over
remove_verification_key: retiring preserves the key data for auditing and can be reversed with
unretire_version.
In the current testnet deployment, key management is controlled by sudo. The transition to on-chain governance (with time-locked proposals and multi-sig) is planned for mainnet. There is no automated deprecation scheduler — old version removal is a manual operation.
For the technical details of the pallet — storage layout, extrinsics, events, Runtime API, and proof encoding — see ZK Verifier Reference.