Why some services can not adopt 0-confirmation transactions

Describing the problem

If a service accepts 0-confirmation deposits and they let users withdraw their Bitcoin Cash, then that service is at high risk for exploitation. Below describes how this attack works.

User deposits X amount of tokens into service using 0-confirmation. User attempts to mine a double spend transaction before their broadcasted transaction confirms. If the attack fails, they withdraw their Bitcoin Cash from the service and repeat the attack until they succeed.

There’s three variables to pay attention to in this attack.

  1. The amount of tokens the malicious user is depositing.
  2. The amount of hash power they are mining the double spend transaction with.
  3. The amount of time it takes for the attack to succeed.

It is in the best interests of the malicious user to maximize the amount of tokens they are depositing to the service and to exploit it to its maximum potential. There is no risk of loss to the malicious User. If the attack fails, they withdraw their Bitcoin Cash and try again.

It is important to know that their is no minimum requirement of hashing power to perform this attack. Anyone with any amount of hash power can perform this attack.

The amount of time it takes for the attack to succeed depends mostly on the amount of hash power that is mining the double spend transaction. For example, if the malicious User is only mining with 0.1% of the total hash power. That is 1 / 1000 of the total hash power. If they repeated this attack every single block on the service, they would statistically on average double spend the service in about one week.

Also it is important to know that this attack costs little to nothing for the attacker. When they successfully mine a block with their double spend transaction they also keep the block reward, as the network will accept their block that includes the double spend transaction.

Why should we care?

First we need to understand that there are many services in the crypto space that let users deposit and withdraw their Bitcoin Cash. Exchanges are probably the first to come to mind, but there are others like read.cash, noise.cash, tipping bots, blockchain.poker, etc. The deposit and withdraw feature is a very popular way that users interact with services in the crypto space, it is useful and convenient, and I see many more services in the future having this feature. However… They will not be able to adopt 0-confirmation deposits in the current state, as they would put themselves at high risk for exploitation. Even double spend proofs do not fix this problem.

There are ways for services to mitigate this attack, but it requires them to be very proactive and build advanced tools to let them detect suspicious user behavior. It would cost each service a lot of time & money to mitigate this risk of attack on their own, and they would still be at risk even after building these tools for themselves.

So what do we do about it?

  • First, we should make everyone aware in the space about this problem, send them to this thread to take a look at the problem and get a productive discussion going. We should warn any service that lets users deposit and withdraw to not adopt 0-confirmation, until we find a solution, or at minimum to proceed with great caution.

  • Second, we should gather the smart technical minded people in the Bitcoin Cash community and come up with creative solutions.

  • Third, we should discuss each proposed solution and weigh the pros and cons.

  • Fourth, decide on a final solution, reach consensus, build it, test it, and push it out.


Well I think you are somewhat late to the discussion here.

We already have 2 solutions of which one is in the implementation stage and one in the design stage:

  • Double Spend Proofs (Can be already used and implemented now)
  • Zero Confirmation Escrows (Incoming, no ETA yet)

So I consider this matter as To Be Sorted Out Soon™.

1 Like


Also, there is nothing to get consensus for, In My Opinion we have already achieved consensus, you just weren’t aware of it.

Have to agree with @ShadowOfHarbringer here, in that Double Spend Proofs should be used by services which fit your scenario (allowing withdrawal of 0-conf’ed deposits, and potentially large deposits at that).

So, if they notice proofs of double-spending repeatedly for deposits of some identifiable “client” (you need to be minimally identifiable in some way on such a service, in order to later withdraw any funds) then they can just throttle or freeze such a misbehaving account.

Double Spend Proofs are supported on various node clients, and I believe Fulcrum also has an API for them.

There is of course a difficulty that a user could register another account to continue their trials, after they’ve been blocked out by DSPs.

I think it’s more sensible for such a service to require more than zero confirmations for larger amounts, or even to downgrade a user’s limits if they detect DSPs on deposits.

1 Like

How can double spend proofs stop this attack if the attacker never broadcasts the double spending transaction and only tries to secretly mine it themselves?

1 Like

Here is a better description of the attack posted by @bitarchitect in Telegram.

(1) A miner sends e.g. 5000 BCH to an exchange (e.g. @markdavidlamb 's CoinFlex - he was outlining the risks of this particular scenario).
(2) With 0 conf in place and seemingly okay DS proofs (which only work if a 2nd DS transaction is relayed to nodes), the exchange could credit the big balance, never identifying any 2nd DS transaction at all.
(3) The miner keeps mining, is lucky to mine a block, but intentionally excludes the transaction (1) from the block, replacing it with another transaction to themselves that was never broadcasted to the network and thus bypassed the DS proofs.
(4) Hence, such a miner-initiated DS attack beats 0 conf and DS proofs as we know them now, and the miner walks away with a big balance on an exchange that was not confirmed in a BCH block.


So, DSP is somewhere between 0-conf and 1-conf:

  • With 0-conf, if miners didn’t care then anyone seeing the offending TX could mine it (even though most won’t - but they could).
  • With DSP, they still could, but DSP would alert the service that there’s a theft being attempted and identify the culprit.

DSP detracts the thief only from using the P2P network to broadcast his transaction to as many miners as possible, hoping that some of them don’t have double-spend prevention as a policy.

What you describe is that the thief can collude with miners and send them the TX covertly out of band, so it won’t be caught by the DSP alarm until it’s too late.

I think there’s no way to easily solve this without changing assumptions about mining:

  • Mining is fully anonymous
  • Mining is fully free, as in, free to arbitrarily choose which TX-es get in
  • Mining is uncensorable
  • Mining is permissionless
  • Seeing a TX can be plausibly denied
  • The next block is always an unknown until it’s mined
  • When compliant (chains of) blocks are competing, the greater PoW wins

What if we make DSP proof part of consensus so they would allow the double-spent output to be claimed as fee by other miners? A “magical” unlocking script OP_DSP which can unlock regardless of the locking script, as long as the provided DSP checks out. Suddenly, all other miners have incentive to:

  • monitor DSP
  • not allow the stolen funds to be moved
  • construct a TX to steal the funds from the thief as soon as they see one

This would bring 0-conf security to 1-conf level, because the thief would have to not only get the offending TX in, but then also spend it once more in order to secure it against being claimed by other miners.

DSP would be too big to fit inside unlocking bytecode, right? We’d have to somehow hack it to make it fit. There was already talk about increasing the size. Or, make it detached and put just the hash in the unlocking script, and find a place for the preimage somewhere inside the TX that’d claim the thief’s funds.

1 Like

Isn’t this similar to what Zero Confirmation Escrows by @bitjson does?

Ah yes, it’s the same idea but because it wants to avoid consensus changes it’s way more convoluted and requires action from the payer, who has to craft his TX in a specific way in order for it to be claimable by miners if he later changes his mind and decides to try to steal.

With the detached DSP, the payer (potential thief) has no say in the matter because the whole network consensus becomes that stealing will be punished, and proven attempts will instead find their way into miners pockets.
It would require consensus change, but ordinary P2PKH payments would be supported.

You could make this into a CHIP and name it “Double Spend Proofs 2.0” but I am not entirely sure yet this is safe and doesn’t have any Bitcoin-breaking rules.

1 Like

Neither am I, that kind of thing would require careful study as with all consensus changes. It may be worth the trouble because it could forever make 0-conf almost as safe as 1-conf.

While the attack is doable and valid, it also is not very practical for most scenarios. It will basically

  • Only be potentially profitable when attacking exchanges
  • Only for bigger sums of money: having even an 0.1% miner business costs so much to setup, that it will be too much hassle to do such attack for less than $1000-$2000 of value. At least it would be for me.
  • Does not apply for physical goods and services, even up to $10000, because you risk with your person / your reputation / your life and resources via potential jail time as the attack can be easily detected and stopped even before goods are delivered.

While better technologies to prevent the attack are in the works (ZECs), in the meantime exchanges can simply allow 0-conf for smaller amounts and require 1 confirmation for bigger amounts.

to expand on why this attack is not very practical here is a more complete list of possible mitigations (of which only the last one is not straightforward):

  • kyc
  • smaller limit for 0conf (say 100-1000 $)
  • remove the credited bch in case of double spend (either by 0conf dsproof or actual 1conf DS)
  • require more (than 0) confirmations for withdrawals
  • detect suspicious repeated deposits

Collaterals only work if the recipient is the sole custodian of the collateral. ZCE nor miner forfeits dont work.

I haven’t really seen anyone citing a technical reason as to why a shorter blocktime (in the 1-2 minute range) is problematic. The only pushback I have seen is the implicit assumption that 1 minute block times don’t enable many more use cases than 10 minute block times… There is an implicit binary assumption that since block times can’t be 1 second, then it doesn’t really make much difference if they are 10 minutes vs 1 minute. Speaking from my own experience, I can say I have ruled out a long list of specific use cases because of 10 minute blocks (that would have worked just fine with 1 minute blocks). I understand these are all theoretical vaporware in my head, but I can’t help but think many other developers are having the same issue and simply choosing alternative ecosystems as the solution.

Now if the reason for staying with 10 minute blocks is because changing the block time would start another war – Then I 100% agree with not changing the block time – no problems there. But if the reason is because people think 1 minute block times don’t enable significant utility, then I think that position should be seriously reconsidered. I think it’s safe to make the assumption that latency in transactions is a serious consideration in choosing payment networks. Just because you can’t think of these use cases, doesn’t mean other people aren’t. I have thought of many, and I’m sure that doesn’t even account for 0.0001% of the potential use cases of 1 minute blocks. At the very minimum, I think people need to at least acknowledge a very very large tradeoff is being made here – Blocktime is not negligible design parameter.

As everyone knows, there are a hundred different ways to mitigate the 0-conf challenge, but none of them rival the simplicity and elegance of a 1 minute block time. It’s super simple with little technical downside.


I don’t have a formed opinion on what the block frequency should be.

But I can confirm that there is currently a lack of a decision-making mechanism capable of making a decision as important as this, without breaking us.

Without a decentralized voting mechanism it is not possible to make any minimally disruptive decision.

I will make a formal proposal in the coming weeks.

1 Like

correction - in this specific case a zce type collateral might actually be helpful

The zce’s aren’t realistic for multiple reasons. They “technically” work, but there are too many real-world implementation challenges.