Double Spend Proofs making regular payments more secure
Sep 25, 2020
Several years ago I invented an exciting concept of a Double Spend Proof. To understand what it is, let’s first figure out what a double spend is.
When I use Bitcoin Cash and I pay someone, I spend a coin, a coin is just a digital file and it is easy to copy.
This raises the question if I could copy the coin and in that way get more money.
This is what the following video is about, you can skip the video if you prefer reading.
Introduction
Several years ago I invented an exciting concept of a Double Spend Proof. To understand what it is, let’s first figure out what a double spend is.
When I use Bitcoin Cash and I pay someone, I spend a coin, a coin is just a digital file and it is easy to copy. This raises the question if I could copy the coin and in that way get more money. Satoshi Nakamoto fixed that back in 2009 with the blockchain.
In blockchain the blocks are only valid when they do not include double spends. This gives miners the incentive to keep the chain safe because they won’t get paid if they break this rule.
A transaction included in a block on the chain is quite safe. Being confirmed in the chain makes this transaction irreversible.
In our current banking system reaching such an irreversible state may take weeks.
A transaction getting mined in a block takes on average 10 minutes. Before this we say that a transaction is unconfirmed. Or that it has zero confirmations. Zero-conf for short.
Zero-conf transactions are quite useful for many cases, for instance if you go to the store and want to pay for your groceries with Bitcoin Cash. It would not be a good user experience if you every customer was forced to wait 10 minutes. Imagine the queues!
For zero-conf payments to be safe everyone needs to run their node with the same policies and logic. The most important of this is the first-seen rule. The first-seen rule means that a node will always keep and mine the first transaction it has seen in case of double spends.
To understand how to execute an attack, take a merchant called Bob and a customer called Dean.
Dean has selected some items in the store and is now at the cash-registry, he pays with Bitcoin Cash.
Dean has prepared two transactions: one that pays the merchant to appear to be a nice customer. And he privately created another transaction that spends a copy of the same coin but instead pays himself. These two transactions double spend each other and can’t both be confirmed in a block. One of them will be rejected.
Dean is gambling that the transaction that gets confirmed will be the one in which he pays himself. That means that the merchant Bob won’t get paid.
We know that nodes accept only the first transaction they see when it comes to double spends, so we have to be fast since the entire world will know about a transaction within 3 to 5 seconds of it being sent to the network.
Dean figures that he can use the slowness of the Internet. Messages don’t go faster than this. To go around the planet takes more than a second. So, he figures, he can send a transaction first to some miners on the other side of the planet and then halve a second later send the merchant his transaction. The distance means that both will get their transactions at the same time.
Bob the merchant will only see the transaction that pays him while the far away miner will see the one that pays Dean.
Now every 10th or so time that Dean tries this trick, he will get his goods and he will also get his own money back. He just double spent Bob the merchant!
Double Spend Proofs
What would be really nice is if there was a simple way for Bob the merchant to detect that Dean was indeed trying to scam him. Most people would agree that the moment Dean sent his second transaction to the network he was morally wrong, he tried to scam Bob by buying something and not paying.
This brings in the double spend proof. The DSProof takes some parts from each of the double spending transactions and combines them in one. Bob the merchant will want to receive this proof via his wallet software and get a notification from his wallet that Dean is trying to scam him.
Bob the merchant can then choose what to do. It will most likely include him telling Dean to leave the store and never come back. The important part is that Bob did not get scammed.
What is this Double Spend Proof?
The DSProof is a message that uses the fact that two transactions spending the same coin will need to cryptographically sign that coin. Once per transaction. These two signatures are the essence of a double spend proof. Users can verify those signatures to independently confirm that the proof is valid. That there really was a double spend.
When Dean sent his transaction to the merchant and another to the other side of the world he started an avalanche where both transactions spread through the world. Half the nodes will see one transaction, the other half sees the other. The boundary nodes will see both transactions and those nodes will be the ones creating the double spend proof message.
This message will equally be spread all over the world and eventually reach the merchant. We should do some testing on how fast that is, the expectation is that the merchant will see it in less than 3 seconds. This will make it fast enough for the merchant to accept zero-conf without having to fear double spend.
There are various known versions of double spending attacks and DSProof protects you against most of them. We have some limitations at this time, we only create DSProof for Pay-to-Public-Key-Hash type of transactions and we don’t protect against miner-assisted double spends.
This is Ok for now as this covers over 99% of what we see on the net today.
When can we use DSProof?
The first milestone is fast approaching where the majority of the Bitcoin Cash full nodes create and broadcast DSProof messages to their peers.
This alone won’t actually have much effect on most people. Next step is to make the rest of the ecosystem use this.
The goal we now have is for all services to be upgraded so each zero-conf transaction can be checked for a DSProof. Rest services, block explorers and similar services that process zero-conf transactions should provide a DSProof field to accompany each transaction.
We want to make it easy for wallets and websites to realize that when there is no DSProof for a zero-conf transaction that this makes accepting them much more safe.
So when I go to a block explorer I want to see a nice green icon saying “no known DSProof!” for each zero-conf transaction.
The next step after that is to make all wallets, point of sales and payment services start to support DSProofs.
I would ask anyone that builds a wallet to consider how they can add support for Double Spend proofs, and last I’d like to ask any users that want to be notified when they are being scammed to ask the maker of their wallet of choice to add that support.