Two-party CoinJoin with SIGHASH_SINGLE:
13. SIGHASH_SINGLE — Signing One Output
Overview
SIGHASH_SINGLE (value 0x03) commits to all inputs but only to the one output whose index matches the current input's index. It allows other outputs to be freely added without invalidating the signature.
Commits to:
✓ All inputs (their outpoints)
✓ The output at the same index as the signed input
✓ Current input's sequence
Does NOT commit to:
✗ Outputs at other indices
✗ Other inputs' sequences
The Correspondence Rule
With SIGHASH_SINGLE, input N is bound to output N:
Input 0 (SIGHASH_SINGLE) ─────────── binds to ──→ Output 0
Input 1 (SIGHASH_ALL) ─────────── binds to ──→ Outputs 0, 1, 2... (all)
Input 2 (SIGHASH_SINGLE) ─────────── binds to ──→ Output 2
Outputs 1, 3, 4... are "open" and can be added by anyone
Serialization Logic
def apply_sighash_single(tx_copy, input_index):
if input_index >= len(tx_copy.outputs):
# The famous SIGHASH_SINGLE bug:
# No corresponding output exists; the protocol returns hash of 1
return None # signals the 0x01 hash quirk
# Truncate outputs to just index + 1
tx_copy.outputs = tx_copy.outputs[:input_index + 1]
# Null out all outputs before input_index
for i in range(input_index):
tx_copy.outputs[i].value = 0xFFFFFFFFFFFFFFFF # -1 as uint64
tx_copy.outputs[i].script = b''
# Set other inputs' sequences to 0
for i, inp in enumerate(tx_copy.inputs):
if i != input_index:
inp.sequence = 0
return tx_copy
Use in Fee Bumping and CoinJoin
SIGHASH_SINGLE is useful when multiple parties are assembling a transaction and each wants to control their own output:
# Two-party CoinJoin with SIGHASH_SINGLE:
Transaction:
Input 0 (Alice, 1.0 BTC, SIGHASH_SINGLE) → Output 0 (Alice, 0.9 BTC, her change)
Input 1 (Bob, 1.0 BTC, SIGHASH_SINGLE) → Output 1 (Bob, 0.9 BTC, his change)
Alice signs: commits to [Input 0, Input 1 outpoints] + [Output 0]
Bob signs: commits to [Input 0, Input 1 outpoints] + [Output 1]
Neither Alice nor Bob needs to know the other's output script to sign.
Lightning Network Payment Channels
SIGHASH_SINGLE combined with SIGHASH_ANYONECANPAY is used in some Lightning channel constructions to allow fee bumping through transaction splicing:
# Initial commitment transaction uses SIGHASH_SINGLE|ANYONECANPAY
# so external inputs/outputs can be added to pay fees without
# invalidating the channel partners' signatures
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: