CHIP 2025-11: Unsettled Inputs Break Zero-confirmation Transactions

Unsettled Inputs Break Zero-confirmation Transactions

    Title: Unsettled Inputs Break Zero-confirmation Transactions
    Type: Standards
    Layer: Applications
    Maintainer: 2qx
    Status: Draft
    Initial Publication Date: 2025-11-25
    Latest Revision Date: 2025-11-25
    Version: 0.1.0-draft

Summary

A rule is proposed for wallet implementers to manage expectations around defi contracts and zero-conf.

Discussion

As this is primarily a problem of coordination among various teams, it should be handy to limit high-level succinct discussion “on the record” to this BCR thread.

Background

For several years, new uses of contracts employing anyone-can-spend miner extractable value (MEV) have been expanding throughout the Bitcoin Cash ecosystem. There has begun to be some conflict, at times, about the implications of these latent features in contracts to the way Bitcoin Cash has historically been used, as cash.

This CHIP is an attempt to reduce conflict by articulating the problem and the minimum wallet requirements to prevent this issue from ever negatively affecting merchants and retail users.

In short, there are now and have always been, transactions possible on the network which are subject to race conditions, reversions and replacement in the mempool. Despite this potentiality, some of these contracts are becoming increasingly useful in a Cambrian Explosion of new systems. Anyone can build these transactions. Some systems are better (or worse) at deploying this feature in a reliable way.

Proposed Solution

In the context of a physical retail environment, of Alice paying a merchant for goods at a point-of-sale (which is of critical importance to the whole project) it would be good to manage expectations about the block confirmations needed in the case of a p2sh input.

Both Alice and the Merchant MUST have clear indication in their respective software if an input to a transaction has an unconfirmed p2sh somewhere in the chain of inputs.

Traditionally, in banking or finance, such funds would be called “unsettled” or “pending”.

As a solution, the following rule is proposed:

If there is any non-p2pkh input in the unconfirmed chain of transactions funding a transaction, a wallet or PoS SHOULD present a message of “pending” or “unsettled” and NOT show the merchant or user any visual indication that could imply the transaction is complete, as it otherwise would be in a zero-confirmation transaction.

There is a LOT of jargon around the industry. This standard proposes the simplest words in a given locale MUST be used for what has traditionally been called a pending or unsettled financial transaction.

While exceptions could be made for well known pay to script hash contracts that are signed, for general contracts, we don’t always have every potential spending path revealed. In addition, as more folks are learning script and weird new things are being built, it may be better to err on the safe side for now.

Along with a rule that BIP44 wallets MUST search all possible xpaths in a known list, we could move towards a common standard of wallet behavior around Bitcoin Cash’s quirks and features.

As it is not a CHIP affecting consensus, industry leaders may adopt it at any time.

Copyright

This document is placed in the public domain.

3 Likes

I love the overall concept of this proposal very much :+1::+1:

We had a lot of discussion on this topic lately, but nobody proposed to do anything actually specific regarding this issue, so I view this as a step in good direction.

I think further work is needed on clarification of how the “pending” payment denial should exactly work, we need more details.

Maybe we can develop a clear behaviour scenario that could be standarized in our entire ecosystem.

Alternative approach:

I wonder if Double Spend Proofs could be modified to also notify all the clients that there is an unspent P2SH input in the unconfirmed chain.

Assuming this could be done, this would also solve the problem. Of course, clients would have to support the new “DSP-2.0” protocol too.

If there’s non-P2PKH ancestor, DSP score will be 0.

The DSP specification is explicit about coverage:

If the transaction does not fit any of the following criteria, do not rely on double-spend-proof, and instead either wait for confirmation or apply more stringent risk management:

The transaction must contain all P2PKH.
The transaction must either be spending only from confirmed UTXOs, or all of its ancestors in mempool must also be all-P2PKH transactions (Optional, requires BIP62).
All of the inputs in the relevant transaction, and its mempool ancestor chain (Optional, requires BIP62), must be signed SIGHASH_ALL without ANYONECANPAY.

And the getdsproofscore will return 0 in non-covered cases:

A value of 0.0 indicates that the tx in question or one of its
mempool ancestors has a dsproof, or that it or one of its mempool
ancestors does not support dsproofs (not P2PKH), so confidence in
this tx should be low.
1 Like

So basically, the problem is already fixed today?

Then why did we even have all the discussions about possible double spends with unconfirmed non-P2KPH higher up in the chain?

1 Like

From Alice’s perspective, where she is either a customer or a merchant, DSP implementation in a wallet/PoS has moved from a “nice to have” to a “must have” in 2025, because p2sh transactions are now much more common.

Alice is not reading the spec. She does not need to know what DSP stands for. She just wants a wallet that works.

I think this is what Alice wants to see:

DSP score Customer Merchant
< 1 pending :warning: unsettled :warning:
1 sent received

In both cases, the transaction has “zero confirmations”, so that jargon isn’t helpful to Alice. And, in neither case did a double spend necessarily occur. And if it did, the score would be zero for true… so, that’s again not helpful.


So moving forward, ALL wallets & PoS terminals need to move toward supporting the Double Spend Proof Spec as a minimum core requirement.

And then, we want to extend the Merchant considerations section to manage Alice’s expectations as a customer too, so that she will be seeing that the payment isn’t confirmed along with the merchant and there is no potential conflict there.

And then, as a community, if someone has a problem with this issue, we say their wallet is defective, and direct them to a better wallet and report the lack of DSP support as an issue to the wallet maintainer.


EDIT:

There should probably be some standard jargon free tooltips for wallet designers to the effect of:

unsettled: :warning: Transaction funds may be reversed or modified. Please wait for confirmation. :warning:

received: Funds are received.

I think that’s all Alice wants to see.

2 Likes

So basically, technologically the problem is solved, but what we can still do is UX standarization across the ecosystem?

Great idea!

How do we start, who do we contact?

my guess would be kallisti, joemar, mathieu, romit, etc… :innocent:

5 Likes

I think Confirmed, Settled (0-conf safe), Unsettled (dsproof or not 0-conf safe) would be good. Hoping others will chime in, otherwise I’ll probably go with this.

I believe that “Confirmed vs Settled” creates an ambiguity about which one is better (and which one is worse) and how much worse the settled is.

The customers/shoppers are gonna start thinking whether the Settled is enough and we are back to starting point - as in people not trusting ds-proofed 0-conf.

How about

Unsettled → Received → Settled

Instead?

1 Like

How about uniform jargon:

  1. pending :warning: (DSP score < 1)
  2. processing (DSP score = 1)
  3. settled (confirmed)

On the other hand, this suggests that “processing” is unfinished, which is super bad for merchants/customers.

I mean I can already imagine customers complaining and flooding support call centre lines that their transaction is still “processing”…

“Pending” and “Processing” mean basically the same thing to me as an end user. And as a seller, it may imply that I should not yet render goods/services.

Shadow makes a good point along the same lines.

We could go with:

  • :warning: Unsettled or Pending (dsproof/not 0-conf safe)
  • Received (0-conf safe)
  • Confirmed (mined)
1 Like

“Confirmed” is OK, assuming you mark “Received” with a certain shade of Green and then use another shade (brighter?) for “Confirmed”.

What I mean is that we do not want to create a preconception that DS-0-conf/Received is not good enough.

Also wallets and PoS systems can have a USD value threshold (like $2000-$10000) above which “Received” is changed to “Pending” to avoid possible risk of miner-assisted attacks.

1 Like

The UX would be such that Received and Confirmed both read as “good to go”. They’d both be green like you said