Architecture

System architecture

How shh stacks on Base, the component map across circuits / contracts / SDK / chain / explorer / app, and the trust and upgrade model that ties them together.

shh is an OP Stack rollup that settles batches to Base. On top of that base layer, each profile exposes a different privacy model — but both reuse the same circuits, Merkle tree, and verifiers.

The stack

                          Ethereum L1
                              │  (settlement of Base)
                          ┌───┴────┐
                          │  Base   │   L2 (OP Stack)
                          └───┬────┘
            standard bridge   │   shielded bridge
                          ┌───┴────────────────────┐
                          │        shh  (L3)        │   OP Stack rollup, single sequencer
                          │  settles batches to Base │
                          ├──────────────────────────┤
   Profile A (full priv) │  ShieldedPool (UTXO)      │  Profile B (open + pool)
                          │  every transfer = note    │  transparent EVM +
                          │                           │  PrivacyPool (fixed denom + ASP)
                          └──────────────────────────┘

Component map

LayerComponentTechPackage
ProofsUTXO join-split, Privacy-Pool withdrawCircom + Groth16packages/circuits
ContractsPools, Merkle tree, bridges, verifiersSolidity (Hardhat)packages/contracts
ClientNotes, Merkle, witness/proof genTypeScriptpackages/sdk
Chainop-geth / op-node / op-batcher / op-proposerDocker Composeinfra/op-stack
IndexerBlock explorerBlockscoutinfra/explorer
AppDeposit / transfer / withdraw UI + backendNext.jsapps/web

Two profiles, one core

Profile A makes the ShieldedPool the canonical value layer — balances are UTXO note commitments in a Poseidon Merkle tree and transfers are join-split proofs. Profile B is a transparent EVM L3 where privacy is opt-in via the fixed-denomination PrivacyPool, whose withdrawals require an Association Set membership proof. The difference is which contract is the default value path and what the predeploys/genesis set — the cryptography underneath is identical.

Trust & upgrade model

  • Trusted setup — Groth16 requires a per-circuit trusted setup. Mainnet uses a multi-party Powers-of-Tau ceremony; dev uses a single-contributor setup that is never for production funds.
  • Upgradeability — contracts deploy behind a timelock-governed proxy with an emergency pause.
  • Immutability — verifiers and Merkle parameters are immutable per deployment.