How Dogenado Works
Dogenado uses zero-knowledge cryptography to enable private transactions. This page explains the technical concepts behind the protocol.
The Privacy Problem
On public blockchains like DogeOS, all transactions are visible. Anyone can:
- See your wallet balance
- Track where you send funds
- Analyze your transaction history
- Link your real-world identity to your wallet
Dogenado solves this by breaking the on-chain link between sender and receiver.
Anonymity Pools
The core of Dogenado consists of anonymity pools - smart contracts that:
- Accept fixed-denomination deposits
- Store all deposits together in a Merkle tree
- Allow withdrawals using zero-knowledge proofs
┌─────────────────────────────────────────────────────┐
│ Anonymity Pool │
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ 100 │ │ 100 │ │ 100 │ │ 100 │ │ 100 │ ... │
│ │USDC │ │USDC │ │USDC │ │USDC │ │USDC │ │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
│ ↑ ↑ ↑ ↑ ↑ │
│ User A User B User C User D User E │
│ │
│ Anyone can withdraw 100 USDC with valid proof │
│ No way to know which deposit it came from │
└─────────────────────────────────────────────────────┘
Zero-Knowledge Proofs
Dogenado uses zkSNARKs (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) - a cryptographic method that allows you to prove something is true without revealing any information about it.
What We Prove
When you withdraw, you prove:
- You know a secret that corresponds to a deposit in the pool
- The deposit exists in the Merkle tree
- You haven't withdrawn before (nullifier hasn't been used)
What Stays Hidden
The proof reveals nothing about:
- Which deposit is yours
- When you deposited
- Your original wallet address
The Deposit Process
sequenceDiagram
participant User
participant Wallet
participant Contract
User->>Wallet: Initiate deposit
Wallet->>Wallet: Generate random secret + nullifier
Wallet->>Wallet: Compute commitment = hash(secret, nullifier)
Wallet->>Contract: deposit(commitment, amount)
Contract->>Contract: Add commitment to Merkle tree
Contract->>Wallet: Emit Deposit event
Wallet->>User: Return secret note
Step by Step:
-
Generate Secrets: Your browser generates two random values:
- Secret: Random 31-byte value
- Nullifier: Random 31-byte value
-
Compute Commitment: These are hashed together using Pedersen hash:
commitment = PedersenHash(nullifier, secret) -
Deposit: The commitment is stored in the smart contract's Merkle tree
-
Receive Note: You get a note containing your secret and nullifier:
dogenado-usdc100-1-0x[commitment][nullifier][secret]
SAVE YOUR NOTE SECURELY! This is the only way to withdraw your funds. If lost, funds are unrecoverable.
The Withdrawal Process
sequenceDiagram
participant User
participant Browser
participant Service
participant Contract
User->>Browser: Paste note + recipient address
Browser->>Browser: Parse secret + nullifier from note
Browser->>Browser: Compute Merkle proof
Browser->>Browser: Generate ZK proof (30-60 seconds)
Browser->>Service: Submit proof + recipient
Service->>Contract: withdraw(proof, nullifier, recipient)
Contract->>Contract: Verify proof
Contract->>Contract: Mark nullifier as spent
Contract->>User: Transfer tokens to recipient
Step by Step:
-
Parse Note: Extract secret and nullifier from your note
-
Compute Merkle Proof: Find your commitment in the tree and generate a path proof
-
Generate ZK Proof: Create a zero-knowledge proof that proves:
- You know the secret for a commitment in the tree
- The nullifier hash hasn't been used
-
Submit Withdrawal: The proof is submitted to the smart contract
-
Receive Funds: Contract verifies the proof and sends tokens to your recipient address
The Nullifier System
To prevent double-spending, each deposit has a nullifier:
nullifierHash = hash(nullifier)
When you withdraw:
- The nullifier hash is computed
- Contract checks if this hash was used before
- If unused, withdrawal proceeds and hash is marked as spent
- If used, withdrawal is rejected
This ensures each deposit can only be withdrawn once, without revealing which deposit it was.
Merkle Trees
All commitments are stored in a Merkle tree - a data structure that allows efficient proofs of membership:
Root
/ \
H12 H34
/ \ / \
H1 H2 H3 H4
| | | |
C1 C2 C3 C4
(deposits/commitments)
To prove your deposit exists, you only need:
- Your commitment
- The sibling hashes along the path to the root
This is much more efficient than checking every deposit.
Timelock Withdrawals (Optional)
For enhanced security, Dogenado offers timelock withdrawals:
| Option | Delay | Use Case |
|---|---|---|
| Instant | 0 | Quick access when needed |
| 1 Hour | 3600s | Balance speed and security |
| 24 Hours | 86400s | Maximum privacy |
Longer delays increase privacy by:
- Allowing more deposits to accumulate
- Making timing analysis harder
- Reducing correlation between deposit and withdrawal times
Privacy Considerations
The strength of your privacy depends on:
- Anonymity Set Size: More deposits = better privacy
- Time Between Deposit and Withdrawal: Longer = better
- Withdrawal Amount: Using exact deposit amounts
- Recipient Address: Should be a fresh address
See Tips for Anonymity for best practices.