One of the first things a Bitcoin newbie hears is how the system is ‘designed to prevent double spending’. This feature is indeed a proper advantage of crypto payments compared to some traditional payment methods and it deserves to be touted as such.
However almost all explanations of the actual prevention process that I’ve seen so far invariably approach the subject from a fraud prevention standpoint, as if everyone who attempts to double spend is always a bad person. That really is not the case — a double spend attempt without special preparations and access to huge computing resources has no chance of success and is nothing but an exercise in stupidity. So let us please stop thinking about this only in terms of crookery!
Contrary to what you might first think, not all double (or multiple) spending attempts are canceled. They are handled by the blockchain much more elegantly than that. The way the Bitcoin protocol copes with double spend attempts is just another example of the amazing simplicity and mastery that makes the whole project so awesome.
I should begin by stating the following guiding principle:
Bitcoin attaches no moral ambiguity to the act of attempted double spending.
There are no Blockchain Gods who stay behind your back and take notes every time you attempt to reuse the same UTXO. Your priceless soul is not forfeited when you press that ‘Sign Transaction’ button the second time, or the third, or the fourth… Well, four times is definitely spamming, and you should stop doing that.
How and When Bitcoin Transactions are Validated (in broad strokes)
When you create a spend transaction and broadcast it to the network, it goes into the mempool: a part of the memory of each Bitcoin node set aside for incoming transactions just like yours. Getting a transaction onto the mempool is a two-stage process: your wallet sends its message to all Bitcoin nodes it can reach directly, and these nodes forward it to their own peers, until every node on the full Bitcoin node network has a copy. (This usually takes mere seconds.) Your transaction then sits patiently and waits for the ‘Eureka’ moment when a lucky mining node discovers a new block.
Once that happens, the winning node goes through the transactions in its mempool and tests each one for several conditions. Is the key you have provided allowed to spend the outputs? Are the outputs themselves valid (i.e. not already spent elsewhere)? If your transaction satisfies these checks, the node will add it to the freshly minted block.
Submission ≠ Validation
Mempool submission and validation don’t happen immediately nor simultaneously. There is a distinct difference between the moment a transaction is included into the mempool of each node and the moment it is picked up for validation. That delay can be minutes, hours or days… and it can depend on the size of the transaction fee.
You may ask, but why doesn’t each node scan its mempool and reject a second transaction if it already has seen a transaction that spends the same outputs?
The thing is, Bitcoin has no concept of time as you and I see it. Because this is a distributed network that spans the globe, network nodes come online and go down all the time, and the network latency between each node can vary wildly, it just makes no sense to keep a timed log of inbound events.
For the same reason, a Bitcoin node won’t reject a transaction because another one just like it came first. It has no idea of time and can’t judge which transaction is older. To Bitcoin, all unconfirmed transactions are equal. The protocol will not try to second guess the user’s intent.
The Role of Bitcoin Fees in Transaction Processing Order
All Bitcoin users understand intuitively the purpose of fees as a reward for including the transaction into the blockchain. The actual size of the fee is the most common source of grievances, leading to stuck transactions, delays and disappointments. The reason for this is that mining nodes do not include transactions in blocks on a first come, first served basis. Instead, all nodes sort unconfirmed Bitcoin transactions by fee size, largest fee on top1
That is why unconfirmed transactions that carry low fees are showing up in the mempool at the same rate (almost instantly) as their high fee conuterparts, yet are likely to be picked up much, much later — especially during times when the mining blocks are packed full.
Transaction equality ends at the mempool.
Because transactions are not validated upon submission to the pool, it is perfectly possible that at any given moment the mempool may contain multiple transactions using the same unspent output(s). The Bitcoin network doesn’t try to judge intent when it detects such double or even multiple spend attempts. It just makes sure that only one of these attempts is included in the blockchain. The fee-based prioritization of transactions takes care of that: once any of the transaction is included into a block, all subsequent transactions that try to spend the same UTXO will become invalid by definition and will be dropped from the mempool.
Why Does All of This Matter
The way double spend attempts are handled by the Bitcoin protocol gives options to users. Now that we’ve established that attempted double spend does not necessarily means you’re a bad person, here is how you can use it for a good purpose:
Double spending provides an easy way to fix stuck transactions.
See how elegant this is? If an important transaction has not cleared for a long time because of low fee, you can generate an identical transaction from the same UTXO(s) but this time set aside a bigger fee. This new transaction will propagate through the mempool and will end up higher on the waiting list. Once a node validates it and posts it on the blockchain, all other transactions that use the same input(s) will be dropped from the mempool.
This procedure is called ‘Replace-by-Fee’ (RBF) and is one of the two ways methods to speed up a transaction (the other one is called ‘Child Pays for Parent’ (CPFP) and is not actually a part of the Bitcoin protocol but rather a strategy to incentivize mining nodes to include unprocessed older transactions by spending their outputs along with higher fees).
The only time double spending can be an issue is if you decide to trust a transaction without any confirmations. Blockchain explorers will report such attempts, here is how blockchain.info does it. But even then, if you use common sense, you can recognize potentially valid transaction from ones created with malicious intent.
Once a valid transaction clears, the double spend attempts will be dropped from the mempool. Some blockchain explorers (e.g. blockchain.info) will then stop reporting double spend attempts when viewing the successful transaction. Others (e.g. blockcypher.com) will keep this info on permanent record and will link from the valid transaction page to the TXID of the invalid transaction (which will be empty).
Here is how the same RBF transaction looks in both cases:
Do you want to know more about this? You can check this much, much more detailed & technical article by Bitcoin expert and author Rich Apodaca that teaches you how to clear a stuck Bitcoin transaction.
One of the great pleasures I get from learning about Bitcoin is discovering an endless supply of elegant solutions to tough challenges. This gives me the confidence that in the future Bitcoin will be able to overcome even larger technical obstacles and allows me to just enjoy the ride.
Have you used Replace-by-Fee to unstick a delayed transaction? What are your favorite tricks to ensure your Bitcoin payments clear quickly and inexpensively? Let me know in the comments below.