How to Protect Against Replay Attacks
Jeff Garzik recently reverted opt-in replay protection on the btc1 GitHub. This is causing some anxiety as many believe this lack of replay protection will cause all sorts of horrible things on the network.
In this article, I’m going to explain a few ways to protect against replay attacks regardless of whether replay protection is implemented. This will require explaining how Bitcoin transactions work and how UTXOs are consumed and hopefully, you, dear reader, will have a better grasp of what you will need to do to be safe going forward.
In order to understand what we need to do to guard against replay attacks, we first need to dig a little bit into how Bitcoin works.
With Bitcoin, you actually don’t have a single big balance, even if all the payments have been sent to a single address. What you have are a bunch of little payments to you called UTXOs.
UTXO stands for unspent transaction output, and you can think of them like bank checks that someone has sent to you. You can only spend what you have and these checks add up to the balance your wallet shows.
When you spend some amount of Bitcoins, what your wallet does is it uses one or more of these checks that have been sent to you and spends them as inputs. So if Alice sent you 5 bitcoins and Bob sent you 3 bitcoins and you’re sending 8 to Charlie, your wallet knows to use both the “5 bitcoin” check and the “3 bitcoin” check as inputs. You send 8 bitcoins to Charlie and he now has an “8 bitcoin” check (note this example ignores fees).
An important feature of UTXOs is that the entire UTXO has to be spent any time a UTXO is used as an input. That is, if you’re spending a check your friend sent you, you have to spend all of it.
So if you only have a single check (UTXO) that’s 100 Bitcoins and only want to send 0.001 to someone, what do you do? This is where you use the fact that you can send Bitcoins to multiple people in a single transaction. You can send 0.001 to someone and send 99.9985 to yourself (and give 0.0005 as a fee to the miner). You will now have a new check (UTXO) that’s 99.9985 Bitcoins that comprise of your balance.
This way, once a UTXO is spent, it can be ignored. It’s either spent or unspent with no in-between state, which makes the code a lot simpler.