How Mixoor keeps your Solana wallet actions separate
Mixoor runs Poseidon hash commitments, Merkle trees, and strict nullifier checks on Solana to break wallet linkage and credibly block double-spends. Here’s how it actually works when you move coins.
By Jorge Rodriguez · 7 min read read · 2026-07-01T11:00:00-03:00
How commitments and nullifiers break on-chain wallet linkage
Solana’s fully public ledger means everyone sees every move. You spin up a fresh wallet and fund it? Game over. Source is obvious. Mixoor solves this: move SOL or USDC between wallets, no clean on-chain trail. The core tech? Commitments and nullifiers.
Let’s get into the weeds: Mixoor’s design uses Poseidon commitments and one-time nullifiers on top of a Merkle tree, all with Groth16 ZK proofs. Result? You get privacy and double-spend defense, no LARP, enforced entirely on Solana.
Why generic token transfers leak wallet relationships
You know the deal: Solana txs are fast and cheap, but it’s all see-through. Every transfer, every recipient, every asset is on display. Feet in wet concrete. On-chain explorers and wallet clustering tools can reconstruct it all in seconds.
| Technique | Exposes | Can be linked by... |
|---|---|---|
| Direct SOL/USDC transfer | Source wallet, recipient wallet, time, amount | Anyone (Solana Explorer) |
| Obfuscation via multi-hop manual transfer | Funding patterns, relays, likely linkage | Analysts, bubble maps |
| Mixoor transfer | Deposit and withdrawal, but with no direct link | Requires attacking ZK proof or deanonymizing with external data |
If you’re building or auditing, you need to get how Mixoor severs linkage. The whole thing hangs on trustless, on-chain cryptography, not magic, just solid math.
Commitments: How deposits become unlinked claims
User drops a deposit to Mixoor, client-side spins a secret note and hashes it up with deposit data via Poseidon. That hash? Commitment. Gets parked as a Merkle leaf, nothing about your wallet address goes in.
Deposit receipt is the note itself. Lose it, funds stuck forever. Dev view: these commitments are bare hashes (no wallet key), one-time and unlinkable without outside clues.
Nullifiers: Catching double-spends and rejecting duplicates
A commitment proves a deposit, but without guardrails, you could try to double-spend. Nullifier fixes this. It’s another hash from the note. For each spend, client generates a ZK proof and a new nullifierhash.
Mixoor smart contract checks if that nullifierhash is already on-chain. If yes, tx fails. Only one withdraw per note, regardless of which wallet tries.
Inside the Mixoor protocol: Walkthrough for devs
Here’s the system, start to finish: privacy checks, proof, and enforcement all native to Solana.
You (the user) spin a random note client-side. That and your deposit info get Poseidon-hashed, commitment goes onto the on-chain Merkle tree, then you fund the deposit.
Merkle root bumps with each new leaf. No addresses or transaction paths get logged in the tree.
Withdrawal wallet shows a ZK proof that it knows a real commitment path to the root and tosses in a fresh nullifierhash.
Smart contract checks the Groth16 proof, confirms the nullifierhash hasn't shown up before, and sends funds to the withdrawal wallet.
Try to reuse a note (thus a nullifier)? Smart contract bricks the tx. Nullifiers only live once.
How commitments and nullifiers reduce wallet linkage (and what they can't do)
So, deposit wallet and withdrawal wallet don’t have to overlap. On-chain, there’s no binding between the two. Explorers see a deposit, then a withdrawal, but can’t match them up unless you screw up with side info.
But don’t kid yourself, nothing’s bulletproof. Timing, amounts, or sloppy wallet habits can leak connects. Mixoor just cranks up the difficulty for linkage. You still have to operate smart.
Groth16 proofs protect the link between deposit and withdrawal.
Only cryptographic commitments, never wallet addresses, are in the pool.
Nullifierhash ensures one withdrawal per note, trustless and automatic.
All checks are contract-enforced and source-verifiable on Solana.
Checklists for audits and integration
Auditing or integrating Mixoor? Here’s what actually matters under the hood.
What exactly is a commitment in Mixoor?
Commitment is a Poseidon hash of your note and deposit. Gets saved as a Merkle leaf. Nothing about your wallet, just the hash.
How does the nullifier prevent double-spending?
Each withdrawal burns a nullifierhash from your original note. Smart contract looks for duplicates. If found already, withdrawal fails.
Can someone trace my Mixoor deposit to my withdrawal?
No on-chain trail if you avoid wallet reuse and obvious patterns. Forensic matching is harder, not impossible.
What happens if I lose my note?
Note is your only claim to the coins. Lose it and funds are stuck, no recourse. Back these up or kiss it goodbye.
Check out the live protocol and audit the contracts to see how commitments and nullifiers actually run.
Try Mixoor on Solana →