zkVerify Architecture: The Full Picture
The components that make zkVerify work
zkVerify is not a single monolithic verifier. It is a modular chain where each piece handles a specific job. Understanding the architecture helps you reason about what happens to your proof from submission to settlement.
The Substrate runtime
zkVerify is built on Substrate, the same framework powering Polkadot. Substrate gives the chain a modular runtime where functionality is bundled into discrete pallets, each compiled into the runtime and upgradeable without a hard fork.
This matters because new proof systems can be added as first-class citizens. Not as bolt-on smart contracts, but as native runtime modules with the same access and performance as everything else on the chain.
Verifier pallets
Each supported proof system has its own verifier pallet, a Rust module that implements that proof system's native verification algorithm.
When a proof arrives:
- The runtime reads the proof type from the submission - It routes the proof to the correct pallet - The pallet runs verification against the registered verification key - The result is recorded on-chain as an attestation
This is what native verification means in practice. There is no translation layer, no proof wrapping, no re-encoding. Groth16 gets verified as Groth16. RISC Zero gets verified as RISC Zero. Each proof type is a first-class citizen.
ParaVerifier
Introduced in Node Update 1.1.0 in December 2025, ParaVerifier is a dedicated parachain built specifically for high-throughput proof verification. It separates verification workload from general chain computation, targeting significantly higher proof volume capacity than running everything through the main runtime.
This reflects where zkVerify is heading architecturally: specialized environments for specialized jobs.
The aggregation engine
Once proofs are verified, the aggregation engine batches them by domain. Multiple verified attestations are collected into a Merkle tree. The root of that tree is what gets published to the destination chain.
One important clarification: the aggregation is not itself a ZK proof. It is a digitally signed message containing the Merkle root of all verified proofs in a batch. Smart contracts on the destination chain verify inclusion via a standard Merkle proof, not by re-running any ZK verification.
This is where the economics work out. Many proofs get verified individually on zkVerify at low cost. Their attestations are batched into one Merkle root. One transaction posts that root to the destination chain. The settlement cost is split across every proof in the batch.
The settlement smart contract
zkVerify deploys a smart contract on destination chains including Ethereum, Base, and others. This contract receives and stores incoming Merkle roots from the aggregation engine.
Your application contract checks against this stored root using a Merkle path, not the original proof. There is no re-verification and no large proof data appearing on-chain. The destination chain only ever sees a compact hash.
VFlow
VFlow is zkVerify's EVM-compatible System Parachain. Its primary purpose is to enable bridging of the VFY token from the zkVerify mainchain to EVM chains via XCM.
As a secondary capability, VFlow is a fully-fledged EVM environment. Developers can deploy and interact with contracts using standard tooling like Foundry, Hardhat, and Remix.
One practical note: connecting to VFlow requires a wallet that supports both EVM and Substrate chains simultaneously. The recommended options are SubWallet or Talisman. MetaMask alone does not work because it is EVM-only. If your keys are in MetaMask, export your seed phrase and import it into SubWallet or Talisman before trying to connect.
The full flow
<div style={{ marginTop: "1.5rem", marginBottom: "1.5rem" }}> !zkVerify </div>
The original proof never appears on the destination chain. Only the Merkle path does. That is the entire point.
Answer the quiz correctly to continue →
What is the role of a verifier pallet in zkVerify's architecture?