Skip to main content

Proof Submitter Flow

Proof Submitter flow

The flow will be the following:

  1. A proof submitter (rollup / zkApp) submits the proof via the submitProof extrinsic of the appropriate verification pallet. The proof leaf value will be:

        leaf_digest = keccak256(keccak256(verifier_ctx), hash(vk), keccak256(public_inputs_bytes))

    Every verifier should define its verifier_ctx (a unique byte sequence), how to hash the verification key and how to extract a byte sequence from public inputs. Then, to produce the leaf_digest, we apply the previous formula.

  2. If the proof is valid, it is relayed by the consensus and eventually included in a Mainchain block; otherwise the transaction reverts with an error.

  3. The failing transaction will be included in the block anyway, and the user will pay fees for it. This is to prevent DoS attacks.

  4. When the block in which the proof was posted is finalized, a Poe::NewElement event is emitted, containing the digest of the proof value and the id of the attestation in which the proof will be included attestation_id.

  5. When a predefined policy is met, a Merkle tree for the attestation_id is generated and a Poe::NewAttestation event is emitted with id and attestation fields.

  6. The Proof Submitter can retrieve the Merkle Path of the submitted proof via the poe_proofPath extrinsic of the PoE pallet, supplying the attestation_id and a digest of the proof proof_hash


Some pallets have been developed to accommodate the requirements:

  • Verifiers where each one defines the proof, verification key and public inputs types, implements the verification logic and defines how to compute the 3 hashes that compose the final statement hash that represent the proof leaf value:
  • proof_of_existence: The attestation pallet that defines the logic to generate new attestations and the corresponding events once that the conditions of a given policy are met.
  • proof_of_existence_rpc: Defines the interface and the logic of the proofPath RPC call.