Skip to main content

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?

Upgradeable circuits

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.

Multiple versions coexist

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.

Auditable and transparent

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.

Governance-controlled

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.

Your funds are safe across 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.

Proofs match the version their note was created under

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:

Retirement is the critical step, not activation

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.


MVP status

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.