The inevitable demise of unconfirmed Bitcoin transactions

In Bitcoin there’s a practice roughly equivalent to accepting a check which hasn’t been committed by the block chain yet, known as accepting unconfirmed transactions or ‘zeroconf’. There’s some kerfluffle going on as to whether zeroconf functionality is a fantasy or important functionality.

To say that zeroconf doesn’t work is an oversimplification. Zeroconf works okay… for now. But if it’s used at any meaninful scale an unstoppable conspiracy will inevitably emerge to exploit those relying on it. Rather than wait for disaster to strike, Bitcoin development should plan to cease zeroconf support in a scheduled and orderly manner, with the changeover happening before either the conspiracy gets built or harm is done to the functionality which zeroconf support conflicts with.

What zeroconf is

How would one start trying to build a system like Bitcoin without already knowing how Bitcoin works? A quick first pass would be Bitcoin without the blockchain: A system where all transactions are broadcast everywhere, and whenever a coin is spent it’s replaced by a new one with the recipient’s public key. Let’s call this hypothetical system ‘Bitpeso’. This system on its face seems tantalizingly close to working well. Peers can verify that they got a payment and prove it to their own recipients. There’s just one little problem: there’s no protection against double spends. While this sounds like a small issue to fix, it’s completely accurate to say that the entirety of the block chain, mining, mining rewards, etc. exist solely to produce a glorified database for the prevention of double spends. This is not hyperbole or a dis, it’s a straightforward factual statement of what functionality Bitcoin has over Bitpeso.

A full discussion of what mining is and why it works in the (rather unfortunate) way it does is beyond the scope of this essay. For now, the important points are: There are deep technical reasons for why mining works the way it does, the output of mining is a new set of committed transactions added to the top of the block chain every few minutes, and it’s added by a (somewhat randomly picked) miner, who has discretion of which new transactions to include, but can neither forge new transactions nor undo ones which were previously committed. (I’m simplifying a bit for understandability, the details don’t change the essence of what’s going on any.)

Zeroconf is an attempt to leverage the Bitpeso functionality subset of Bitcoin for actual security. The idea is that if you send a transaction to a lot of nodes and verify that it’s been widely distributed and that conflicting double-spend transactions aren’t, then it’s reasonable to assume that whichever miner mints the next block will commit that transaction as expected. Aside from the unsettling fact that this is subverting all the protections of Bitcoin in favor of the limited protections of Bitpeso, most of it can be done semi-reasonably. Transactions can be distributed quickly. Peers can follow a social convention of not accepting cheating substitutions. And miners can have a policy of using whichever transactions their local full node has. It’s this last assumption which is ironically both the most reliable in practice today and completely fatal in the long run.

How to get zeroconf to work for now

The first step in maximizing Bitpeso security is to distribute your transactions as quickly as possible. The Bitcoin backbone network does that well. (It’s a bit centralized but that’s okay for these purposes.) The second thing is to check many disparate peers and verify that they have gotten the correct transaction. There isn’t any standard library for doing this, but it’s fairly straightforward engineering.

Next you need to make on peers follow a favorable social convention for when to let transactions get replaced. The current standard implementation is ‘never’, which is an unusually altruistic thing for Bitcoin nodes to do because they’re directly giving up coin when they don’t accept a replacement transaction with a higher fee. Laudable as that may sound, once the transaction rate limit rate is consistently hit this policy will cause transactions whose fees are too low to get stuck, unable to raise their fee to get accepted. This is obviously a bad thing. There’s a change in the pipeline which allows fee increases but avoids damage to zeroconf by not allowing any of the old inputs or outputs to be changed, only new ones added. That helps, but makes transactions get much larger, and stops working completely if the wallet increases the fee enough times that it runs out of new coins to add. Clearly there’s a strong tension between supporting transaction fees and supporting zeroconf. While not fatal to zeroconf in and of itself, this is a compelling reason to drop zeroconf support.

It would also be good to get more full nodes running and decrease mining centralization. Both of those are problems not just for zeroconf but for Bitcoin generally, and are unfortunately unlikely to get dramatically better any time soon.

Finally, it’s vitally necessary for zeroconf that miners all use whatever transactions their own full node has locally for their block minting. This is currently almost universally followed, but ironically it’s the fatal flaw which will inevitably sink the whole system.

How to make zeroconf stop working

The way to take advantage of a vendor accepting zeroconf is to pay off a miner directly. Let the ‘good’ transaction propagate across all the Bitcoin full nodes like it’s supposed to, but send an alternative ‘bad’ transaction directly to the miner which splits the output between the person making the payment and the miner, with none going to the output for the ‘good’ payment. At first blush this sounds difficult to do: You’d have to somehow track down individual miners and negotiate a shady deal with them, putting both you and them at risk of public embarrassment or criminal prosecution, and having to expend a fair amount of effort to do this with each miner individually.

But all of this can be automated with a darknet service. Miners can identify with the service by proving that they’re the owners of a previous mining reward target, and wallet software can automatically send an alternative transaction for each of the miners which splits output between the wallet itself, the miner, and the darknet service. The darknet service then accepts these transactions and forwards them to the appropriate miners. Suddenly setting up kickbacks is anonymous and trivial. I’m not going to work on building such a service, because it would be a bad thing, but inevitably somebody will. There are no good countermeasures. The endgame is that zeroconf-accepting vendors either give up or accept fraud on a massive scale.

Zeroconf transactions still demonstrate something, of course. For example, they show that whoever is making the transaction at least has access to the keys they claim, and other Bitpeso level guarantees. But the strong form of security which Bitcoin provides simply isn’t provided. A zeroconf accepting Bitcoin credit card is mostly an ordinary credit card, with credit card security features.

What the plan should be

A schedule should be made of when (not if, when) the reference implementation of Bitcoin starts shipping with default behavior of accepting replacement transactions without restriction. That should happen after accepting zeroconf is no longer semi-reasonable (which it still probably is), but before transaction fee pressure starts. Jeff Garzik, one of the core Bitcoin developers, suggested that a reasonable time frame is between 6 and 12 months from now, which sounds reasonable to me as well. Whatever is done, the timeframe should be set clearly in advance, so everyone will have a chance to prepare.