BattleZips
  • Awesome Circom
  • 🔬Theory
    • Prerequisite Knowledge
    • Resources
      • White Papers & PDF's
      • Blogs and Writeups
      • Videos
      • Important Entities
      • Communities
    • Proving Schemes
    • Primitives
      • Hash Functions
      • Public Key Cryptosystems
        • Note on L1 key registry → L2 hot key + callback to circuit-optimized hash functions
        • ECDSA & secp256k1
        • EdDSA
      • Merkle Trees
        • What is a Merkle Tree?
        • What is a merkle proof of inclusion?
        • zk-kit
        • Incremental Merkle Trees
        • Sparse Merkle Trees
        • Tree Arity (Binary, Quinary)
      • Semaphore
      • Arithmetic Circuits
  • 🏗️Development
    • Circom Language
      • Installation
      • IDE
      • Signals and Variables
      • Signal Assignment and Constraint Generation
      • Conditional Statements
      • Components and Templates
      • Circuit Compilation
      • Syntax
    • SnarkJS
      • Proving Schemes
      • Powers of Tau
      • ZK Keys
      • Zero Knowledge Proofs
      • On-Chain ZKP
      • Page 2
    • circomlib
      • Basic Math Constraints
      • Multiplexing
      • Hashing
      • EdDSA
      • circomlibjs
    • circom-tester
    • hardhat-circom
    • SHIELD
    • Circomspect
  • 🌆Ecosystem
    • Circom vs Other Solutions
      • Domain-Specific Languages
      • ZK Virtual Machines
      • ZK Ethereum Virtual Machines
    • Communities to Join
    • Recorded Content
    • Projects
  • 🛳️Examples
    • BattleZips V1
      • On the BattleZips Project
      • Docs holder
        • Join Game UML Sequence Diagram
        • Play Game UML Sequence Diagram
        • End Game UML Sequence Diagram
      • ZK Privacy Stack
      • Deploying Artifacts to Prod
      • Browser Client
    • RollupNC
      • Smart Contracts
      • Account/ State Tree
      • Transaction Tree
      • Layer 1 Deposits to Layer 2
      • Layer 2 Transacting
      • Layer 2 Withdrawals to Layer 1
Powered by GitBook
On this page
  1. Examples
  2. RollupNC

Smart Contracts

PreviousRollupNCNextAccount/ State Tree

Last updated 2 years ago

-

The point of RollupNC is to facilitate off-chain transfers of arbitrary ERC20 or the EVM gas token. On deployment, the gas token is available. Using the token registry, anyone can request a token be added to the L2 network and the permissioned sequencer can approve a token for deposit and transfer on the L2 network.

The Rollup contract is a point of contact that is only used for entry and exit. Depositing into the L2 contract requires no zero knowledge proof, however it does make use of a temporary merkle tree in the contract to batch in groups of 2^n deposits onto L2. The rollup operator confirms deposits are batched in using a zero knowledge proof. The same proof is used to commit L2 state transfers on-chain.

Once a depositor has made an L2 withdrawal transaction that has been committed to L1 in the state root, depositors can withdraw the exact amount of tokens in the L2 withdrawal transaction on L1.

Since EdDSA keys are much more efficient to use in zero knowledge than the ECDSA keys used on L1, this code base a mechanism by which pubkeys of the two cryptosystems can be associated with each-other in a verifiable manner.

Note: we describe this code base with the Poseidon hash function - the original version uses MiMC instead. The outcome is almost identical (Poseidon is actually inferior in this case) but do not be alarmed or confused by the switching of the two as the only consequence is efficiency.

These mechanics are explained in more detail in the following sections.

Deploying Poseidon Contracts

Using specific to the number of inputs you need. This is limited to 6 inputs, meaning you mush do multiple rounds of Poseidon hashing to hash larger quantities of inputs together.

Deployment () is as follows, using hardhat-deploy:

const { ethers } = require('hardhat');

/**
 * Deploy All Contracts
 */
module.exports = async ({ run, ethers, network, deployments }) => {

    // deploy Poseidon hasher for 2 inputs
    const poseidonT3ABI = poseidonContract.generateABI(2);
    const poseidonT3Bytecode = poseidonContract.createCode(2);
    const poseidonT3Factory = new ethers.ContractFactory(poseidonT3ABI, poseidonT3Bytecode, operator);
    const poseidonT3 = await poseidonT3Factory.deploy();
    await poseidonT3.deployed();
    
    // deploy Poseidon hasher for 5 inputs
    const poseidonT6ABI = poseidonContract.generateABI(5);
    const poseidonT6Bytecode = poseidonContract.createCode(5);
    const poseidonT6Factory = new ethers.ContractFactory(poseidonT6ABI, poseidonT6Bytecode, operator);
    const poseidonT6 = await poseidonT6Factory.deploy();
    await poseidonT6.deployed();

    .
    .
    .
    
    // link Poseidon contracts in to RollupNC contract
    const { address: rollupAddress } = await deployments.deploy('RollupNC', {
        .
        .
        .
        libraries: {
            PoseidonT3: poseidonT3.address,
            PoseidonT6: poseidonT6.address
        }
    })
})
pragma solidity 0.8.15;
import "./libraries/Poseidon.sol";

unction deposit(
    uint256[2] memory pubkey,
    uint256 amount,
    uint256 tokenType
) public payable {
    .
    .
    .
    
    // generate a deposit leaf (account leaf)
    uint256 depositHash = PoseidonT6.poseidon(
        [pubkey[0], pubkey[1], amount, uint256(0), tokenType]
    );
    
    .
    .
    .
}

From here, you can easily perform Poseidon hashes in Solidity as shown below (and in the [])

🛳️
Token Registry
Proof-carrying Rollup
circomlibjs, you can generate a Poseidon hashing contract
seen in BattleZips' RollupNC updated repo
BattleZips RollupNC repo
library