Using UPA in your ZK app

ZK apps before UPA

In a typical ZK app:

  • The client makes requests of the app contract. Each request contains public inputsPIs along with a proof that those public inputs were valid.

  • The app contract calls a verify function that checks whether a request's (PIs, proof) pair is valid or not. If the request was valid, then the app contract executes the corresponding business logic.

ZK apps after UPA

In a UPA-integrated ZK app, the UPA contract takes over the responsibility of proof verification. The client now makes a AppRequest in two stages.

  • First, they submit (PIs, Proof) to the UPA contract. If the proof is valid, then after some time the PIs are marked as verified in the UPA contract.

  • Second, they make an AppRequest(PIs). The app contract checks whether PIs has been marked as verified on the UPA contract. If so, the app goes on to execute the request.

The client saves gas because UPA verifies batches of proofs rather than individual proofs.

What the UPA contract does

The UPA contract verifies batches of proofs as follows.

  • The UPA contract receives a submit(PIs, Proof) call.

  • An off-chain proof aggregator adds the (PIs, Proof) pair to a batch. Then it produces a ZK proof aggregatedProof that all of the (PIs, proof) pairs in that batch are valid. It then sends the aggregatedProof to the UPA contract.

  • The UPA contract only needs to verify a single proof: aggregatedProof. If correct, then the contract marks all of the proofs in the corresponding batch as valid.​

Last updated