This message is meant to inform participants of attempts of double spending an unconfirmed transaction by providing cryptographic provable evidence that one UTXO entry was spent twice by the owner(s) of the funds.
The basic concept of a double spend is that (at least) one unspent output is spent twice in different transactions which forces miners to pick one of them to mine.
Cryptographic signatures in Bitcoin Cash follow the "fork-id" algorithm described [here](/protocol/forks/replay-protected-sighash).
Since a hash of the transaction is signed, the protocol sends only the intermediate components used to build the preimage for the hash, while still allowing receivers to validate both signatures of the same public key, and therefore proving that a double spend has taken place.
In response to an inventory message, any peer can issue a [getdata](/protocol/network/messages/getdata) message which will cause a reply with the following message.
This type of message is **`dsproof-beta`** but will be changed to another identifier once double-spend proofs move out of beta and is finalized.
| previous [transaction output](/protocol/blockchain/transaction#transaction-output)'s transaction hash | 32 | sha256<sup>[(LE)](/protocol/misc/endian/little)</sup> | The **transaction hash** of the output being spent |
| previous [transaction output](/protocol/blockchain/transaction#transaction-output)'s index | 4 | unsigned integer<sup>[(LE)](/protocol/misc/endian/little)</sup> | The **index** of the transaction output being spent |
| first spender | variable | spender<sup>[(BE)](/protocol/misc/endian/big)</sup> | The preimage data structure needed to validate a transaction's signature. |
| second spender | variable | spender<sup>[(BE)](/protocol/misc/endian/big)</sup> | The preimage data structure needed to validate a transaction's signature. |
Each field in the (below) table's `description` column loosely corresponds to the name of the preimage component used when generating transaction signatures per the [transaction signing algorithm](/protocol/blockchain/transaction/transaction-signing).
| Field | Length | Format | [Signature Preimage](/protocol/blockchain/transaction/transaction-signing#preimage-format) Component | Description |
| push-data count | variable | [variable length integer](/protocol/formats/variable-length-integer) | | Number of push-data objects within in the push-data list |
As the forkid [specification](/protocol/blockchain/transaction/transaction-signing#preimage-format) details, the digest algorithm hashes 10 items in order to receive a sha256 hash, which is then signed.
The transaction that first spent the output within the node's [memory pool](/protocol/blockchain/memory-pool), can be used to get the public key required to validate that the signature within the `push-data` field of the double spend proof is correct.
Transactions that spend all, confirmed, P2PKH outputs with all inputs signed `SIGHASH_ALL` without `ANYONECANPAY`, are double-spend-proof's "protected transactions".
Bitcoin Verde supports an extended form of the `dsproof-beta` message.
For P2PKH outputs, the format is as described above for compatibility with other nodes.
For all other script types, the following changes are made to the existing data:
1.`hash prevoutputs` is always the non-zero version of hash (e.g. for `SIGHASH_ALL`, **not**`ANYONECANPAY` hash types).
2.`hash sequence` is always the non-zero version of the hash (e.g. for `SIGHASH_ALL`, **not**`ANYONECANPAY` hash types).
3.`hash outputs` is always all zero (0x00) bytes.
4.`push data` is defined to be the values push by every (push) operation in the unlocking scripts, except for P2SH, where the last value (the redeem script) is left off.
The following extra data is also appended after the second spender:
| hash type count | 1 byte | [variable length integer](/protocol/formats/variable-length-integer) | The number of hashes to follow (always 2 with current signature rules). |
| hash type indicator 0 | 1 byte | byte | The hash type of the following hash (always 0x01 for `SIGHASH_ALL`). |
| hash outputs 0 | 32 bytes | sha256 | The hash outputs, as used in the signature preimage for a `SIGHASH_ALL` signature. |
| hash type indicator 1 | 1 byte | byte | The hash type of the following hash (always 0x03 for `SIGHASH_SINGLE`). |
| hash outputs 1 | 32 bytes | sha256 | The hash outputs, as used in the signature preimage for a `SIGHASH_SINGLE` signature. |
This format corresponds with Bitcoin Verde's proposal for an alternate double spend proof message that supports all script types.