Privacy Architecture
Imagine you have money in your wallet. Normally, when you use it on a blockchain, everyone can see how much you have, who you pay, and how much you send. Orbinum changes this using zero-knowledge cryptography, allowing you to make transactions where these details remain private.
This guide shows you how that privacy system works, what operations you can perform, and what guarantees you get.
What can you do in Orbinum?
Deposit public tokens into the private pool. Your funds become confidential.
Send private tokens to other users without revealing amounts or identities.
Withdraw tokens from the private pool to a public account visible on the blockchain.
Share a disclosure key to prove the exact contents of a note — value and asset — without granting spending capability.
How it works: The Shielded Pool
The shielded pool is like a common vault where all private funds are mixed together. When you deposit tokens, they become notes — cryptographic receipts that only you can spend.
A note is like a private bill that contains:
- Amount: how many tokens it represents
- Asset ID: what type of token it is (ORB, USDT, etc.)
- Owner: who can spend it (your public key)
- Blinding: a random number to hide all of the above
Operation 1: Shield (Deposit to Private Pool)
When you shield, you convert public tokens into private ones by depositing them into the shielded pool.
Step-by-step flow
Your wallet generates a note with your amount, asset ID, public key, and a random blinding factor
commitment = Poseidon(amount, asset_id, owner_pubkey, blinding)
The runtime locks your public tokens and adds the commitment to the active Merkle tree of the forest
Your wallet keeps the complete note so it can spend it later. Losing the device is recoverable: the note's contents also travel on-chain inside an encrypted memo that only your wallet can read, so importing a note backup or running a manual rescan rebuilds the vault. What you must not lose is access to the wallet itself — the keys derive from its signature. See Note Discovery.
What is still public?
- Your public account deposited funds
- The deposit timestamp
- Commitment (meaningless hash)
- Exact amount deposited
- Asset ID (partially)
- Blinding factor
- Where those funds will go next
Batching
shield_batch deposits up to 20 notes in a single extrinsic, each with its own asset, amount,
commitment, and memo. It emits one Shielded event per operation and fails atomically — if any
single deposit is invalid, the whole batch reverts.
Useful when splitting a balance into several denominations at once, which is also good privacy hygiene: a set of round-numbered notes blends into the crowd better than one distinctive amount.
Operation 2: Private Transfer
A private transfer moves funds within the shielded pool without revealing who sends, who receives, or how much is sent.
Step-by-step flow
Your wallet searches for notes you own with enough balance to cover the amount to send
One note for the recipient (e.g., 50 USDT) and one for you with the change (e.g., 50 USDT remaining)
This takes 2-5 seconds. The proof validates that:
- You own the input notes
- The notes are in the Merkle tree
- Amounts balance (input = output)
- Nullifiers are correct
The runtime verifies the ZK proof (~15ms), marks nullifiers as spent, and adds the new commitments
What remains public?
- A private transaction occurred
- Nullifiers (meaningless hashes)
- New commitments (meaningless hashes)
- Transaction timestamp
- Who sent
- Who received
- How much was sent
- Which asset was used
- Relationship between inputs and outputs
A nullifier is a unique hash calculated from a note when you spend it. It's published on-chain to prevent that same note from being spent twice (double-spending). Without your private key, no one can link the nullifier to the original commitment, maintaining your privacy.
Operation 3: Unshield (Withdrawal from Private Pool)
Unshield takes tokens out of the private pool and sends them to a public account. This operation reveals the amount and the recipient.
Step-by-step flow
Choose a note with sufficient balance for the withdrawal
The proof demonstrates you own the note and that the amount is correct, without revealing other details
Includes: ZK proof, nullifier, amount to withdraw, and recipient's public address
The runtime verifies the proof, marks the nullifier as spent, and transfers tokens to the public account
What remains public?
- Exact amount withdrawn
- Public recipient
- Asset ID
- Timestamp
- Who withdrew the funds
- Where the funds came from
- How much balance remained in the note
- Previous history of those funds
Unshield links your private identity with a public account. If someone observes that you deposited 100 USDT and then withdraw 100 USDT shortly after, they can infer those funds are probably yours. For maximum privacy, wait and mix with other users before withdrawing.
Operation 4: Note Disclosure
Note disclosure lets you prove the exact contents of a shielded note to any third party — value, asset, and commitment — without granting any spending capability over that note.
This is done through a disclosure key: a compact, shareable string with the prefix orbdisc: that encodes the plaintext preimage of the on-chain commitment.
Exact token amount, asset ID, owner public key (Baby JubJub Ax), and blinding scalar. The commitment is cryptographically re-verified from these inputs.
Spending key, nullifier, EVM wallet address, and any other note owned by the same key. The recipient cannot spend or freeze the disclosed note.
Verification recomputes Poseidon4(value, asset_id, owner_pk, blinding) and checks it against the embedded commitment. No network call needed.
See the Note Disclosure page for the full technical reference, key format, SDK usage, and security properties.
The Merkle Forest: Where Commitments Live
Commitments are stored in binary Merkle trees of depth 20. Each tree holds up to 1,048,576 notes; when one fills up it is sealed and a fresh tree opens automatically, so the pool never runs out of room.
The Merkle tree allows proving that a note exists in the pool without revealing which one it is. When you spend a note, you generate a "Merkle proof" that demonstrates its inclusion in the tree without pointing to exactly where it is. This breaks the link between deposits and spends, maintaining your privacy.
Sealing and the forest
When a tree reaches its 1,048,576th leaf, the runtime seals it in the same block as that final insert:
- The tree's final root becomes a permanent anchor. Unlike the rolling ring of recent roots, a sealed root never expires — so a note in a sealed tree stays spendable indefinitely, and a proof generated against it does not go stale.
- The active tree resets to empty and subsequent commitments land in the next tree.
Global leaf indices are u32, which caps the forest at roughly 4,096 trees of depth 20. Your wallet
does not need to track any of this: the leaf index determines the tree, and the SDK's treeIdOf
resolves it.
A Merkle proof is proof of membership in one tree. Your anonymity set is the tree holding your note, not the entire pool history.
In practice this bounds the set at ~1M notes rather than fragmenting it in any surprising way, and in a young pool everyone shares tree 0. But it is a real property to be aware of: a note in a sparsely-populated freshly-opened tree has a smaller crowd to hide in than one in a full sealed tree.
Privacy Guarantees and Limitations
✅ What is protected
- Amounts in private transfers (fully hidden)
- Identities of sender and recipient in transfers
- Relationship between inputs and outputs (unlinkable)
- History of a note before being spent
- Individual balances within the pool
⚠️ What remains visible
- Shield/unshield operations link public accounts with the pool
- Transaction timing (when they occur in each block)
- Merkle tree growth (size of the anonymity set)
- Asset type can be partially inferred in some cases
- Unshield amounts are completely public
- Use common denominations: instead of 137.42 USDT, round to 100 or 150
- Wait before unshielding: don't withdraw immediately after depositing
- Mix with other users: the more transactions there are, the larger your anonymity set
- Split funds into multiple notes: don't use a single large note
Multi-Asset: One Pool for All Tokens
Orbinum's shielded pool supports multiple assets (ORB, USDT, DAI, etc.) in the same pool, sharing one anonymity set rather than splitting into a separate tree per asset.
Advantages of the multi-asset approach
All notes from all assets contribute to the same anonymity set, increasing everyone's privacy
Asset-agnostic trees simplify proof verification compared to separate trees per asset
The design facilitates private cross-asset exchanges in future versions
Learn More
📄️ System Overview
Introduction to Orbinum's privacy-focused blockchain architecture.
📄️ Privacy Architecture
How Orbinum enables confidential transactions through zero-knowledge proofs
📄️ Introduction
How Orbinum's Private Vault works, how to recover notes, and what users must know about backup, rescan, and limitations.
📄️ Private Transfer
How private token transfers work in Orbinum — circuit design, BabyJubJub key derivation, dummy note support, and on-chain mechanics.
📄️ Unshield
How the Unshield circuit converts a private note to public tokens — BabyJubJub key derivation, gasless fee, and security properties.
📄️ Note Discovery
How a wallet finds and decrypts the notes that belong to it — encrypted memos, view tags, and stealth addresses.
📄️ Note Disclosure
How note disclosure keys let you prove the contents of a shielded note without surrendering spending capability