# RollupNC

This section is not a full-fledged definition of the use of Circom for proof-carrying rollups. It is meant to be an exploration of and introduction to the concept. We are by no means experts, so we are doing our best to provide this information as we have aggregated it and currently understand its application. Please reach out to us or the [EF PSE Discord](https://discord.gg/f2SfshVW44) (see *ECOSYSTEM > Communities to Join > Discord*) for questions, comments, or concerns on this content.

## RollupNC

[Original Code base](https://github.com/rollupnc/RollupNC) - [Original Codelabs Demo](https://keen-noyce-c29dfa.netlify.app/#5) - BattleZips 2022 Updated Code base

*The Codelabs demo is highly recommended as a primer to the underlying mechanics of RollupNC. However, the Circom code used is somewhat out of date and will not work if compiled in Circom 2.0. You can use the BattleZips updated code base to reconcile these issues, or to simply deploy and run the RollupNC project for yourself quickly.*

### What is RollupNC?

<figure><img src="/files/6XIy6jwsYJrPN93H2C7h" alt=""><figcaption><p>Diagram of state transition in RollupNC<br><a href="https://github.com/rollupnc/RollupNC">https://github.com/rollupnc/RollupNC</a></p></figcaption></figure>

From the RollupNC Readme:

> SNARKs can generate succinct proofs for large computations, which are much faster and computationally easier to verify than they are to compute. This provides a way to "compress" expensive operations by computing them off-chain in a SNARK, and then only verifying the proof on-chain.
>
> RollupNC is an implementation of [rollup](https://github.com/barryWhiteHat/roll_up) in which the relayer **does not** publish transaction data to the main chain, but only publishes the new Merkle root at every update. This provides gas savings but not data availability guarantees: we assume the operator will always provide data to users so they can update their leaf.

RollupNC is a very simplistic proof-carrying rollup demonstrating the use of Zero Knowledge proofs to perform batched, compressed, verifiable computations off-chain whose validity can be proven quickly on-chain.

RollupNC is a very simple rollup- there are three actions a user can perform:

* Deposit an arbitrary ERC20 or Gas token in the ZK L2 contract
* Transfer tokens from one account to another account on Layer 2
* Withdraw tokens from L2, out of the ZK L2 contract, to an Ethereum account

There is a single sequencer responsible for committing state updates to the layer 2 network in this code base. This means that the sequencer could censor new state updates from occurring.

### Moving Beyond RollupNC with Circom: Hermez

The RollupNC functionality is highly limited - after all, the simple act of transferring tokens between accounts is not very useful. [Polygon Hermez](https://github.com/hermeznetwork/circuits) is a spiritual successor to RollupNC, containing all of the functionality in RollupNC and much more:

* Network validation rights tied to proof of stake
* Network fees for users' actions
* Users can swap tokens like an AMM

### BattleZips' RollupNC Update

In the summer of 2022, [BattleZips did an exploratory upgrade of the RollupNC codebase](https://github.com/battlezips/RollupNC) for the current version of Circom. Some changes, like naming or use of Poseidon over MiMC, are inconsequential to this compendium.

The primary improvement BattleZips makes on RollupNC is the creation of a [modern unit test showing ](https://github.com/BattleZips/RollupNC/blob/master/test/0.js)a *heavily* simplified experience for working with the RollupNC circuits. Chiefly, our use of [@zk-kit/incremental-merkle-tree](https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/incremental-merkle-tree) shows a standardized, efficient way to work with the many merkle trees needed to use the RollupNC circuits and contracts.

```
it('Process Batch #1 (4 new balance leaves)', async () => {
    // construct expected values
    const emptyLeaf = L2Account.emptyRoot(poseidon)
    const coordinatorPubkey = accounts.coordinator.L2.pubkey.map(point => F.toObject(point));
    const coordinatorLeaf = poseidon([...coordinatorPubkey, 0, 0, 0]);
    tree = new IncrementalMerkleTree(_poseidon, 4, 0);
    tree.insert(emptyLeaf);
    tree.insert(F.toObject(coordinatorLeaf));
    tree.insert(accounts.alice.L2.root);
    tree.insert(accounts.bob.L2.root);
    const expected = {
        oldRoot: zeroCache[zeroCache.length - 1],
        newRoot: tree.root
    }
    // construct transaction
    const position = [0, 0];
    const proof = [zeroCache[2], zeroCache[3]];
    const tx = rollup.connect(accounts.coordinator.L1).processDeposits(2, position, proof);
    // verify execution integrity
    await expect(tx).to.emit(rollup, "ConfirmDeposit").withArgs(
        expected.oldRoot,
        expected.newRoot,
        4
    );
})
```

Before, there were many supporting utility functions. While we still need many for transaction and account management, we can offload the work done on merkle trees/ merkle proofs to the imported zk-kit incremental merkle tree.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://battlezips.gitbook.io/battlezips/examples/rollupnc.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
