A Comprehensive Bitcoin CoinJoin Guide
To understand CoinJoin, it would help to understand UTXOs (unspent transaction outputs) and Bitcoin transactions. You can skip this section if you know enough about these, but it may be valuable to read it anyway.
In simple terms, a Bitcoin transaction is made up of inputs and outputs (containing bitcoin amounts) and a digital signature(s) made with a private key.
A good analogy is a bank check, which contains
- Which account the money is coming from
- Who is getting paid
- The amount
- And a signature
Here is a random Bitcoin transaction I copied from the Bitcoin blockchain using the publicly available Bitcoin node https://mempool.space/ (Sorry if this transaction is yours!):
On the left column, five bitcoin amounts were entered as inputs, and they were spent to two different outputs on the right (The total of the amounts on the left nearly equal the amounts on the right; the small difference is collected by the miner of the block).
On the bottom left, the mining fee is calculated: 81,200 sats or 100 sats per byte (of interest, this was an outrageously high and unnecessary fee to offer given the waiting list was not particularly long at the time).
The signature details are not shown, but every node does check that the signatures are valid.
“UTXO” is a horrible, horrible name. While it accurately describes what it is, and it’s understandable by an experienced Bitcoiner, it is complete gobbledygook for someone new. It would be better if it was called “Received Coin” or something similar. Just from my pointing this out, you might already understand what it is.
Even though bitcoins are divisible, think of bitcoin amounts not like a dividable liquid, but of discrete amounts, like coins in a purse. I like to use Bitcoin’s competitor, gold, as an example:
Imagine you received a gold coin weighing 1.2 ounces. And now you want to pay someone 0.2 ounces. You’d have to melt the 1.2 ounce coin and make two coins, one weighing 0.2 ounces for the payment, and the rest as a 1.0-ounce coin for you to keep.
Bitcoin is similar. When you receive 1.2 bitcoin to your wallet, you have a discrete 1.2 bitcoin “received coin” or UTXO. If you wanted to spend 0.2 of that, you can’t break off a piece of it and spend only that; you have to “melt” the entire 1.2 bitcoin amount first by putting it into a transaction. With the transaction, you can divide it up however you want, and send it to as many different addresses as you want, including back to one of your own addresses.
This is where the concept of “change” comes in. To spend 0.2 bitcoin, you take the 1.2 bitcoin as an input to the transaction, and make two outputs; one as payment (0.2 bitcoin), and another (1.0 bitcoin) as change back to you (to one of your own addresses). It would look like this:
Alice’s 1.2 bitcoin sitting in one of her wallets’ addresses has been split into two. The Lambo dealer’s wallet address has received 0.2 bitcoin, and a different address in Alice’s wallet receives 1.0 bitcoin.
One final example – imagine you have the following UTXOs in your wallet, and you need to pay 0.6 bitcoin to someone:
- 0.2 bitcoin
- 0.5 bitcoin
- 0.002 bitcoin
Your transaction would take the 0.2 and 0.5 bitcoin UTXOs and put them into a transaction (and leave the 0.002 bitcoin UTXO alone). The transaction would have two outputs: 0.6 bitcoin as the payment, and 0.1 bitcoin as change. After the transaction, your wallet will have a 0.002 bitcoin UTXO and the 0.1 bitcoin UTXO. Two “coins” in total, with a total balance of 0.102 bitcoin (ignoring mining fees to keep it simple).
What Is A CoinJoin?
Many people do not realise that a single transaction can contain digital signatures by more than one person. Without this ability, CoinJoins are not possible.
A CoinJoin is when two or more people combine their transactions into one transaction, in such a way that it is unclear who owns which coin after the transaction. The ambiguity is created by matching the size of the inputs or the outputs, as shall be seen in the example below.
It is possible for an outsider to track coins as they get spent, to an individual person (whether or not that person’s true identity is known). For example, a coin can be moved from address A, to address B, to address C, and it may be possible to determine that the coins in address C belong to whoever owned Address A. This is the pseudonymous property of Bitcoin. However, because customers of exchanges are forced to submit identification documents (Know Your Customer laws, or “KYC”), then because coins withdrawn from the exchange and sent to address A have a real identity associated with it to certain surveillance companies, they therefore know the identity of who owns address C in the example above. It’s important to appreciate that there is no identification on the blockchain; the true identity information is external to Bitcoin. Only people with access to the exchange’s KYC data can correctly identify who owns a coin. Who are they? They’d be either the exchange, surveillance companies the data is sold to, governments, or hackers.
CoinJoining breaks the Address A to B to C pseudonymous identification link, as I’ll show. As I mentioned, this is achieved by using identical values of UTXOs. For example, here is a CoinJoin:
On the left, there are two inputs to this transaction that belong to two different people, Alice and Bob. Only the people with access to KYC data know that it’s Alice and Bob’s. To everyone else, it’s Person A and Person B.
Two 1.0 bitcoin UTXOs have been created and it is unclear which belongs to Alice (Person A) and which belongs to Bob (Person B). Each has a 50% chance of belonging to Alice, and 50% to Bob. The owner of the 0.2 and 0.5 bitcoin amounts can be deduced quite easily with mathematical logic.
Focusing on Alice, she has received 1.0 bitcoin into one of her wallets’ addresses. It is not completely private; to an outside observer, that 1.0 bitcoin has a 50% chance of belonging to her. To increase her privacy, those coins can be mixed again, but she should mix with someone else, not with Bob.
What Can CoinJoin Do For You?
Hiding your bitcoin from the government? CoinJoining does not hide the size of your KYC (Know Your Customer) bitcoin stack from the government. If you have KYC coins, that means you submitted your ID to an exchange and bought bitcoin with that account. You should assume that the exchange will divulge all your transactions and withdrawals to the government if requested.
So if you purchased 1 bitcoin and withdrew that to your own wallet and then CoinJoined it, it may be impossible for the government to know what address(s) your bitcoin is in, but they still know you own 1 bitcoin. If you sold it, it presumably is the law to report the sale. If they ever pass laws to confiscate bitcoin or to tax unrealised gains, they can know exactly how much you have.
If you claim to not own bitcoin because you lost it all in a boating accident, the coins that are known to be yours before your accident will have to sit there and never move. Once you spend, your tragic boating accident will be revealed as a fraud. For completeness, I’ll say that having mixed your coins prior to the accident helps, but not something I’m advocating. It’s a dangerous strategy.
What it can do though, is when you spend bitcoin, the recipient will not have a record of where that payment came from. I’ll explain. Suppose you have 10 bitcoin in an address, and you use it to pay someone 0.001 bitcoin. The recipient can look up the blockchain and notice that it came from an address holding 10 bitcoins. However, if you mixed your coins, the payment will come from an address holding a much smaller amount, and the history of that smaller amount is unknowable too. This means that all of your other coins will not be revealed, equalling privacy.
Should you do it?
So if you understand that you can’t hide your bitcoin total from the government, and you don’t plan to have a boating accident, and all you want is spending privacy, should you CoinJoin?
Think about this question as you read on, and, know that spending using the Lightning Network is going to be sufficiently private for nearly everyone.
Having said that, if everyone CoinJoined, or if CoinJoining was a default implementation in wallets, privacy is enhanced for everyone even if they don’t attempt it.
Is It Wrong? Is It Illegal? What Are The Risks?
Some people are concerned that one day, mixed bitcoins will be labeled as “tainted” and therefore not accepted on exchanges. That might be true, but it is also an easy problem to circumnavigate. You can simply use the coins to open Lightning channels, and anyone receiving Lightning transactions has no way of knowing the channel was opened with mixed coins.
In addition, you can mix a portion of your coins instead of all of them, to hedge your bets.
How To CoinJoin? Option 1 – Automated Services
There are services available where you submit your coins to a pool for mixing. For example, Samourai’s Whirlpool, Wasabi, or JoinMarket. Each has advantages and disadvantages.
Whirlpool and Wasabi
Both Samourai and Wasabi take a variable fee for offering an automated mixing service. You leave your software running, and the central coordinating program will mix your coins with other paying customers. Price varies depending on mixing settings, but it costs roughly 0.2% of the amount you want to mix, including the service fee and mining fees.
JoinMarket is different. There is still an automated service, however, users’ coins enter mixes based on a free market. Users can either offer their coins for mixing (market “makers”) with others and can earn a fee. Or users can pay these makers to mix their coins with them (“takers”).
As a maker, you need to leave your coins on a hot wallet on a computer, and wait for people to accept your offer, competing with other makers on price and size – it is not certain that your coins will be mixed, or when. There is also a risk of keeping your coins in a hot wallet rather than in cold storage. You are rewarded for this risk by being paid the fee you set (in bitcoin) if your coins are mixed.
As a “taker” although you pay a fee, your coin enters a mix essentially immediately. The time it takes to do one mix depends on when the next Bitcoin block is found by a miner. Overall using JoinMarket sounds interesting and fun to do, however, it is quite a technical challenge to pull it off successfully. It is not ready for the mainstream market. Those with some Linux command line experience at the very least would be able to tackle this.
As I do not generally recommend automated mixing services due to a lack of control over external parameters, I have not made a guide. A little internet search should be fruitful though.
How To CoinJoin? Option 2 – DIY CoinJoin
Generating your own CoinJoin transactions has the advantage of total control, and it saves costs; however, it requires you to coordinate transactions with other people which potentially limits the volume of CoinJoins you can do. It also requires some knowledge about generating CoinJoin transactions, and fully controlling transactions generally.
Also, it’s helpful to have a good understanding of transaction privacy, otherwise, you might inadvertently make an error and undo all your effort.
The biggest advantage I find is exploring the fascinating possibilities. I will explain how to do this, but a prerequisite is to know how to use Electrum Desktop Wallet. You can learn here.
Step 1: Run A Node
It’s important to run your own node. If you don’t, the coins you mix and send to your wallet are no longer private. This is true whether you use an automated mixing service or not. Why? Because without a node your wallet is providing its addresses and IP address to a random node which could be a surveillance company.
There are many good reasons to run a node (I explain six reasons here). I recommend running the MyNode package for beginners (see my MyNode guide). Alternatively, if you have some experience, the fully open-source RaspiBlitz is excellent (my RaspiBlitz Gguide).
Step 2: Create A Private Wallet
You may already have a wallet, but as I mentioned, if it has ever connected to a public node, the addresses in that wallet are not private (even the empty unused ones), so sending private coins there damages privacy.
If you make a new private key using a hardware wallet, make sure it never connects to the hardware wallet’s software/node. For the commonly used Ledger, this is almost impossible. You need to create a seed BEFORE connecting to Ledger Live. Once you connect, Ledger Live potentially records all your addresses and your IP address. But don’t worry, once you do that, you can create a new wallet using the same seed: just add a passphrase, and that particular wallet will be private. The wallet without the passphrase can be discarded, or never used. (I provide much more detail about correct hardware wallet usage here.)
For the Coldcard hardware wallet, this is not a problem, as it never requires you to connect to their software.
Step 3: Find Someone Who Wants To CoinJoin With You
This can be tricky. Contact me, I’m always up for a CoinJoin. As your circle of Bitcoin friends widens, and your skills improve (and theirs) more opportunities will present themselves.
Step 4: Construct A CoinJoin Plan
- Which UTXO you will use
- What address it will go to
- The size of the mixed coin
- Will there be any change
- Where will the change go
- What mining fee to pay
For example, I will take a UTXO of 0.01724084 bitcoin, and spend it as two coins; one as a mixed coin of 0.01 bitcoin, and the other as the change of 0.00724084 bitcoin (the change will actually be a little smaller to pay the mining fee as well).
I’ll then need to plan for my CoinJoin partner to spend a UTXO and create an identical 0.01 bitcoin mixed output. There is nothing special about this output on its own. The only reason it is mixed is because it is identical in size to my 0.01 bitcoin output.
Step 5: Generate Your Transaction And Save It
In Electrum, select the UTXO you want to mix. Find it in the address or coins tab and right-click it, and choose <Spend from>:
Then head over to the <Send> tab, and paste in the address where you want to send the mixed coin to:
Click <Pay> and then <Advanced>
Choose your mining fee, then click <Finalize>.
Ignore the high fee ratio warning: Electrum is getting confused because the transfer is internal. It thinks the payment is tiny due to a coding oversight by the developer.
The <Finalize> button changes to <Export>; click it and save the transaction to a file. If you are using a hardware wallet, you’ll normally need to select an option specifically for hardware wallets:
Notice in the image above it says “include xpubs.” Since we are going to be sharing this unsigned transaction with another person we may not necessarily completely trust, we don’t want to provide that information. An xpub does not allow them to steal coins but it would allow them to see your entire wallet. There is a way around this,but I need to take you through a detour to demonstrate however
The purpose of this detour away from ”How To Make CoinJoins” is to explain how to bypass the requirement to include xpubs in the saved transaction. You’re either going to be signing CoinJoin transactions with a hardware wallet, or with a software wallet on a desktop computer that contains your private key.
Coldcard Hardware Wallet
The Coldcard by default checks that the addresses the coins are being spent from belong to the private key it holds. But remember, a CoinJoin transaction contains UTXO inputs from other peoples’ wallets too.
The way it checks is by requiring the xpubs to be part of the transaction you import to it, and then it can recognise if the addresses contained in the transaction belongs to itself or not.
We need to change this default behaviour to do CoinJoins.
After logging in, go to the <settings> menu, then <multisig wallets>, then <trust PSBT?>. Select “OK” after reading the message and select <Trust PSBT>. You can now sign CoinJoined transactions even if the xpubs for the CoinJoin partners were not supplied – just like a regular software wallet.
Other Hardware Wallets
I have tested the BitBox02 hardware wallet and could not see a similar option to “trust PSBT.” I also tested a CoinJoin and it declined to sign due to an unrecognised input, i.e., it noticed the CoinJoin partner’s input address did not belong to itself. So, I can’t see a way to use the BitBox02 for CoinJoining.
I have not yet tested other hardware wallets; you may wish to do this yourself.
Software Wallet Hop
An alternative is to create a temporary software wallet, and any UTXO destined for CoinJoin can first be sent from the hardware wallet to the software wallet. Then you use the software wallet to construct the CoinJoin. This way, you minimise the amount of bitcoin out of cold storage, but it does add an additional transaction cost.
Air-Gapped Software Wallet
My favorite way is to create your own hardware wallet with an air-gapped Raspberry Pi Zero running Electrum, which you can build yourself quite cheaply by following my linked instructions. And then these instructions will teach you how to do air-gapped spends using QR codes. This is how you’d make a private key from scratch using the device, instead of using a key created by a hardware wallet. You don’t have to use a Pi Zero – you could build an air-gapped desktop computer part by part, making sure there are no Wi-Fi or Bluetooth components. It’s much more pleasurable to use and faster, but also more expensive.
Detour Returns From “How to CoinJoin? Option 2 – DIY CoinJoin”
Continued … Step 5: Generate Your Transaction And Save It
You now know how to bypass the need to save xpubs in your exported transaction. Instead, you can save a transaction this way:
Step 6: CoinJoin Parter Follows Step 5 As Well And Sends You Their UNSIGNED Transaction
After your CoinJoin partner saves his/her transaction to a file, it needs to be sent to whoever is coordinating the CoinJoin. Given that the transaction is going to be published on the public blockchain, the information being sent is not particularly sensitive. But it is still desirable to not divulge your actions to anyone performing internet surveillance.
An easy way to communicate is by using ProtonMail. If both sender and recipient use the service, then messages are encrypted by default. If one user is not using ProtonMail then the message is not encrypted.
A more cumbersome way, but far more interesting (which I wholeheartedly encourage you to learn) is to use public/private key cryptography to encrypt the data yourself and send it across any insecure transmission medium, such as Gmail. Here is a guide I wrote on this.
Step 7: Merging Transactions Into A CoinJoin Transaction With Electrum
Once you receive all the unsigned transactions from one or more of the CoinJoin partners, you should save them to your computer, and start by opening your transaction in Electrum like this:
Then, near the bottom right side of the transaction window, you’ll see a <Combine> button. Click that, and then <Join inputs/outputs>.
There are multiple ways to input the transaction data to Electrum, but just clicking the folder icon to give it a file is the easiest.
After <Load transaction> you’ll see the combined transaction:
Some things about this transaction are worth noting. The highlighted addresses indicate that Electrum recognises the addresses as belonging to itself. Green are receiving addresses, yellow are change addresses.
The transaction has two inputs, one of them recognised as self (green), and four outputs, one of which is to a green (self) receiving address, and another a yellow change address. There is one unhighlighted input that belongs to the CoinJoin partner. There are two unhighlighted outputs that also belong to the CoinJoin partner, one of them is his/her CoinJoin UTXO and the other is change.
Notice in the output window there are two identical amounts of 0.01 bitcoin. One is highlighted as our own, but when viewed on the blockchain, no one will know which of the two belongs to this wallet.
Step 8: Signing
So far so good, but we’re not finished.
The transaction now needs to be signed by each CoinJoin partner. Only when all parties have signed is the transaction valid and can be broadcast. Whoever is the final signer has a certain amount of “power” as they can hold up the transaction. You can decide amongst yourselves who will be last to sign and broadcast.
Let’s say you will be the last to sign. Then you’d export this merged transaction to file, and send it to the CoinJoin partner. They need to load the transaction:
After signing, export to file, and send back to you. If there are many CoinJoin partners, then each person must sign and send it to the next person for signing.
When it comes back to you, you load the transaction, sign it, then click the <Broadcast> button which is to the right of the <Sign> button.
Well done! How cool was that? Now do it again.
If you’ve got a sufficient number of mixed UTXOs, it’s important to know what to do with them:
#1 Never sell for fiat, obviously.
#2 Never merge them with a KYC coin as that undoes the privacy of the mixed coin.
#3 Avoid merging different mixed coins together if you can help it.
#4 Note that the change UTXOs are not private and are still KYC’d coins.
#5 Mixed coins are the coins you can privately spend. Make sure you understand exactly which coins you are spending, and don’t accidentally introduce KYC coins into the input (which merges them). Learning to use a powerful Bitcoin wallet, such as Electrum, helps.
This is a guest post by Arman the Parman. Opinions expressed are entirely their own and do not necessarily reflect those of BTC Inc or Bitcoin Magazine.