# Gas costs

Let's walk through the factors determining the end-to-end gas costs for a ZK app using NEBRA UPA. There are three on-chain steps that can consume gas:

Submitting proofs

on-chain (

**~13-100k gas per proof- depends on submission size**)off-chain (

**0 gas per proof**)

Verifying the aggregated proof (

**~18k gas per proof**)Querying the verification result (

**~22k gas per proof or per submission**)

Summing up these costs, we find that in total:

Applications submitting their proofs on-chain can save as much as

**197k gas**(~80%) per proof.Applications submitting their proofs off-chain can save upwards of

**210k gas**(~85%) per proof.

You can estimate your application's gas savings using our gas calculator at** ****gas.nebra.one**. For simplicity we show gas estimates for an application with four public inputs, but the actual costs for each step will vary a bit depending on the number of public inputs per proof.

### Step 1: Proof Submissions

NEBRA UPA collects **submissions** of one or more proofs and places them in a queue to be aggregated. Note that UPA does not aggregate submission-by-submission. Instead, **aggregated batches** are chosen independently of the way the proofs were submitted.

Applications will have two options for proof submissions: on-chain and off-chain. On-chain submissions cost gas in exchange for censorship-resistance (an aggregator that skips verifying a valid proof can be slashed). Off-chain submissions have no gas cost, but offer weaker censorship resistance.

The current UPA release (v1.2) supports on-chain submission. Off-chain submission will be available soon.

#### Cost of on-chain submission

Due to per-transaction storage costs, using a whole Ethereum transaction to submit a single proof is relatively expensive. Instead, we recommend that apps take advantage of **multi-proof submissions**.

The contracts currently deployed to the Sepolia testnet are initial implementations with large scope for gas optimization, but they serve to illustrate the approximate cost model. Currently, the fixed cost per submission is about **100k gas**. The marginal cost of each additional proof in a submission is about **10k gas** (for processing the additional proof and public input data).

Therefore the per-proof gas cost for an on-chain submission of $M$ proofs is approximately:

The table below shows the measured cost of submissions of different sizes.

Submission Batch Size | Total Gas Cost | Per-proof Gas Cost |
---|---|---|

4 | 132,507 | 33,127 |

8 | 176,102 | 22,013 |

16 | 263,214 | 16,451 |

32 | 437,719 | 13,679 |

#### Cost of off-chain submission

Off-chain submissions have no associated gas cost, but a weaker censorship resistance mechanism: In response to a submission, the aggregator sends back a confirmation that they will aggregate the proof before a certain deadline. If this aggregator misses this deadline then they are subject to slashing.

### Step 2: Verifying the aggregated proof

The current version of NEBRA UPA aggregates proofs into a Halo2-KZG proof. The cost of verifying such a proof in isolation is about **350k gas**, and is roughly independent of batch size. In addition, the UPA contract emits an event and updates its storage to mark each application proof in the batch as verified. This incurs a marginal per-proof cost of about **7k gas**.

Therefore the per-proof gas cost for verifying one batch of $N$ proofs and storing the result is approximately:

The current configuration of NEBRA UPA sets the batch size to $N=32$. With this batch size the aggregated verification cost comes out to **~18k gas** per proof (Etherscan).

### Step 3: Query of the verification result

Once a proof has been verified by the UPA contract, the app contract may query the UPA contract to confirm that the associated public inputs are valid. This typically looks like:

The gas cost of this external contract call is about **22k gas** per proof (assuming four public inputs).

Applications may also query the verification status of an entire submission as follows:

This costs about the same amount of gas as calling `isProofVerified`

.

### Calculation of end-to-end gas savings

#### Without UPA

The total cost for an app to verify an individual Groth16 proof is about **250-270k gas**, which can be broken down into:

Submitting and verifying the proof (

**~250k gas**)Retrieving the verification result

from an external contract (

**~10-20k gas**)from within the app contract (

**0 gas**)

**Using UPA with on-chain submission**

With UPA, assuming submissions of size $M$ and proof aggregations of size $N$, the total end-to-end per-proof gas cost **with on-chain submissions** comes out to about:

Concretely, with submissions of $M=32$ proofs and aggregations of $N=32$ proofs, this per-proof gas cost comes out to

which represents a savings of about **197k gas per proof** (~80%).

**Using UPA with off-chain submission**

The end-to-end gas cost **with off-chain submissions** will be approximately:

With the current UPA configuration of $N=32$, the per-proof cost comes out to

which represents a savings of about **210k gas per proof** (~85%).

Last updated