25 Januar 2021

On Bitcoin: the double meaning of double-spends

Dr. Lewin Boehnke

Dr. Lewin Boehnke

CTO bei Crypto Storage AG und Head of Research bei Crypto Finance AG

Über den Autor

Bitcoin solves the double-spending problem – there was a double-spend – everything is fine

The concept of Bitcoin seems commonplace enough by now that it sometimes feels hard to imagine that just a few years ago a common reaction to „with Bitcoin you can store money on your own hard drive“ was usually somewhere between surprise, disbelief, and rejection. The response: „Great, I’ll just copy that file and send my money to several destinations“.

Nope, that is not how it works. Not at all. The fact that I have not received this reaction for a few years gave me a (seemingly false) sense of assurance that it is now widely accepted that Bitcoin actually does solve the double-spend problem. Not everybody who uses Bitcoin from his mobile app or hardware wallets knows, or even needs to know, how it achieves that. But it did catch me by surprise when headlines with some unfortunate wording last week led to seemingly bewildered tweets with questions in chats that are otherwise high-quality in content. It was clearly born of the misunderstanding. Some of these announcements even made it plausible that the „double-spend“ media attention made a significant contribution to the negative price action over the last week.

So here we go with a fact-based take on the situation:

  • Bitcoin solves the double-spending problem
  • Bitcoin did have a double-spend last week
  • Bitcoin works as intended
  • All of the above is true at the same time

It comes down to nomenclature and the difference between the Bitcoin blockchain and an extra communication layer.

Scarcity is an unexpected property for digital goods, but it is crucial if this good intends to represent money and to retain value. To maintain scarcity, Bitcoin needs to ensure that assets cannot be copied or spent in different transactions. There are a few different concepts that are necessary for the following arguments and I will introduce these first.

  • A transaction references the outputs of previous transactions, consumes them, and creates new transaction outputs. The sum of outputs has to be smaller than the sum of inputs and the difference is being payed to the miner as a fee for swift inclusion into a block.
  • The UTxO set, the set of unspent transaction outputs, are the outputs of previous transactions that have not yet been consumed by another output. A transaction is considered invalid if one of its inputs is invalid, i.e. if it had previously been consumed or if it did not exist in the first place.
  • A block is a set of transactions that a miner chooses to group together and proposes as the next block in the chain. Each block references the previous block on top of which it is building. This chain of references to previous chains make what is called the blockchain. If one of the transactions in the block would be invalid, then the whole block is invalid and will be ignored by the network.

Consequently, with each block that is applied onto the previous chaintip (the highest known block), every validating Bitcoin node updates its UTxO set. Every node knows which UTxOs existed before the block, removes those that were consumed in the block, and adds those that were newly created.

That UTxO set and the global synchronisation with each block is what prevents double-spending in Bitcoin.

Period. I could stop here. Bitcoin has not been breached.

With this hard concept widely accepted, the colloquial use of the phrase „double-spend“ extended to something else. This led to an unfortunate linguistic ambiguity and misunderstanding.

How does a miner know about transactions that are waiting for inclusion into a block? Each transaction has a fee attached to it and a rational miner will choose from the pool of valid outstanding transactions according to those that pay him the most for the space used. He will choose valid transactions diligently to avoid making the block invalid. There has to be a way for users to transfer their transactions to miners so they will be included in a block.

This part of sending valid, but loose, transactions takes place on a different layer than the blockchain runs on. It has little to do with the blockchain itself (except that a newly mined block typically will include some of these floating transactions, thus removing them from this other layer, and it may have reason to invalidate other floating transactions). This pool of valid but loosely floating transactions is called the mempool (an unfortunate name that originates from the implementation detail in the code). The mempool leverages the same network of validating nodes that propagates the blocks to propagate the mempool too, but it is purely optional. I might configure my node to ignore transactions below a certain fee rate, in order to save on bandwidth (though if a transaction makes it into a block, I would encounter it again), while somebody else might configure his node differently. I might see one transaction early that was injected into the network by a peer, while some other node might see it much later. Further, a miner might decide to include a transaction into a block that he received by email from a friend and that was not part of the mempool at all. This transaction went straight from “unknown-to-the-network” to “included-in-a-block”.

So, while the blockchain syncronises globally, the mempool is not syncronised at all and is different for all nodes. A transaction in the mempool is not part of the blockchain, and there are no guarantees for such transactions. On the other hand, if a valid, signed transaction is out there, then the sender can try but cannot prevent that transaction from making it into a block (more on that later). To put it in other terms, if you are a coffee shop and a customer pays with bitcoin, seeing the transaction in the mempool might be sufficient for you to hand him the coffee and let him leave. You choose not to make him wait until the transaction is picked up and has confirmations (blocks built on top of the one that contains the transaction you are interested in), and you take the risk that the transaction does not make it into a block as a cost of doing business and a known risk.

The customer could leave your shop, sign a transaction that spends the same UTxOs as the one he used to pay you, put a higher fee on it or send that competing transaction to his miner friend by email. Now, there are two transactions out there. One that pays for the coffee and another one where the customer payed the money to himself. Only one will eventually make it to the blockchain.

This activity also is referred to as double-spending, but it is actually more of a social engineering attack on a careless merchant. Depending whom you ask, a „double-spend“ is successful only if the same output was spent on the chain twice (this did not happen), or if somebody wanted to walk away with a free coffee and prevent that transaction from ever making it to a chain in the first place (this may have happened).

Both things are already known as Bitcoin’s whitepaper addresses this: nothing to see here, move along.

Except, there is one more point that makes this a bit more peculiar.

As described above, miners mine on top of the current chaintip. And once they find a block, they propagate that block through the network, so that other miners can build on top of their block, thereby cementing the block in the linear chain. The longer the block takes to reach the other miners, the more likely another miner finds a competing block. If that happens, the chain temporarily does not look linear, but has a hydra-like double head. Only one of the two will be the base for other miners to build upon, and the other one will be orphaned. If you did not see that orphaned block at the time that this happened – maybe because you joined later – you will never hear of it. Eventually, the chain will become linear again.

I remember times when the rule-of-thumb was that such an orphan happens about once a day, and about once a week, a double tip could extend two blocks long. This happened if some miners worked on one tip, and others worked on the second tip, and – by chance – the next block was found roughly at the same time.

Having a double tip is very expensive for miners. When electricity is used to mine a block in this situation, a miner has a ~50 percent chance that your block does not make it and the effort and cost was in vain. That is why miners are diligent and spend significant resources to work on the current tip. If some other miner finds a block, they switch to working on that one as soon as possible. The longer you work on a previous tip, the more likely it becomes that you find a block that might be orphaned. With increased communication among miners, the rate of orphans has dropped considerably. It hardly happens anymore. But it is a very normal and well-understood element of miner economics that is addressed in the Bitcoin whitepaper and, thus, is nothing to worry about.

It is also the reason for the recommendation that incoming transactions should only be considered „final“ after a certain number of confirmations. The chance that a transaction is undone becomes exponentially less likely with subsequent confirmations. Six confirmations typically are recommended for high-value transactions.

Coming back to the previous discussion about that coffee, as the prototypical example of a low-value transaction, you might be happy with zero confirmations.

What happened this time around? Both of these unusual things happened at the same time. There was a double tip that resulted in an orphaned block. At the same time, there were competing transactions, and each of the double tips had one of the competing transactions in it.

Unusual? Absolutely. That is why it is being discussed. Out of academic curiosity, a few questions remain. Were the two competing transactions created on purpose or by accident? (yes, that happens) Were both transactions propagated through the peer-to-peer network or was one sent directly to a miner? Did the miners know of the competing transactions at the time, and did one deliberately work on top of an old tip to get the competing transaction in?

We will most likely never know the answer to most of these questions. However, because the value of the competing transaction was the equivalent of USD 21 and the value that the miner put at risk was about USD 200,000, were his block not included in the chain, the intent seems unlikely.

However, most importantly, as unusual as it may be, everything that happened is well within the bounds of how Bitcoin is intended to work, with its properties, risks, and safeguards.

So indeed: nothing to see here, move along.

Read and share with the original LinkedIn article here.