Demo app: Before and after UPA

Demo app using UPA

Client changes

Before UPA: The client directly submits their solution publicInputs, along with a proof:

await demoApp.submitSolution(proof, publicInputs);

After UPA: The client first submits their solution and proof to the UPA contract. Then the client waits for UPA to verify the proof before submitting the solution to the simple-app contract:

const submissionHandle = await upaClient.submitProofs(circuitId, proof, publicInputs);

await upaClient.waitForSubmissionVerified(submissionHandle);

await demoApp.submitSolution(publicInputs);

App smart contract changes

Before UPA: The contract checks that the solution is valid by using this.verifyProof to directly verify the proof on-chain.

function submitSolution(
    bytes calldata proof,
    uint256[4] calldata solution
) public returns (bool r) {
    bool isProofCorrect = this.verifyProof(proof, solution);
    require(isProofCorrect, "Proof was not correct");

After UPA: this.verifyProof is replaced by upaVerifier.isVerified. We don't need to send the proof, only the solution:

function submitSolution(
    uint256[4] calldata solution
) public returns (bool r) {
    bool isProofCorrect = upaVerifier.isVerified(circuitId, solution);
    require(isProofCorrect, "Proof was not correct");

Here, the client saves on gas costs as this proof is not verified individually on-chain.

Demo repository

https://github.com/NebraZKP/demo-app

Last updated

Logo

NEBRA Labs