Signing the Transaction
How Bitcoin transaction signing works — SIGHASH types, the signing digest, and ECDSA signatures that prove ownership.
0steps ·
What You’ll Learn
- What SIGHASH types are and how they control what gets signed
- How to construct the signing digest (the data that gets hashed)
- How ECDSA signatures prove ownership without revealing the private key
Why Signing Is Needed
Inputs reference UTXOs, but anyone can write a transaction that claims to spend your coins. The signature proves that the transaction was authorized by the holder of the private key corresponding to the UTXO’s locking script.
Without a valid signature, nodes reject the transaction. The signature is what turns a wish into an authorization.
SIGHASH Types
Before signing, you choose a SIGHASH type that determines which parts of the transaction the signature covers. This controls what can be modified after signing.
| SIGHASH Type | Value | What Is Signed |
|---|---|---|
| SIGHASH_ALL | 0x01 | All inputs and all outputs |
| SIGHASH_NONE | 0x02 | All inputs, no outputs |
| SIGHASH_SINGLE | 0x03 | All inputs, only the output at the same index |
| SIGHASH_ANYONECANPAY | 0x80 | Combined with above; signs only the current input |
SIGHASH_ALL (0x01) is used in the vast majority of transactions. It means: “I authorize exactly these inputs to be spent on exactly these outputs. Change nothing.”
SIGHASH_ANYONECANPAY | SIGHASH_ALL (0x81) is used for crowdfunding-style transactions where multiple people contribute inputs to a shared set of outputs.
The Signing Digest
The signature does not cover the raw transaction directly. Instead, you construct a signing digest — a hash that commits to the relevant transaction data.
Legacy Signing (pre-SegWit)
For legacy transactions, the process is:
- Start with the serialized transaction
- Replace the current input’s ScriptSig with the previous output’s ScriptPubKey
- Set all other inputs’ ScriptSigs to empty
- Append the SIGHASH type as a 4-byte little-endian value
- Double-SHA256 the result
digest = SHA256(SHA256(modified_tx || sighash_type))
This process must be repeated for each input individually.
SegWit Signing (BIP143)
BIP143 introduced a more efficient signing algorithm for SegWit inputs. Instead of re-serializing the entire transaction for each input, it uses precomputed hashes:
digest = SHA256(SHA256(
version # 4 bytes
hashPrevouts # SHA256d of all input outpoints
hashSequence # SHA256d of all input sequences
outpoint # This input's txid + vout (36 bytes)
scriptCode # The script being satisfied
value # This input's UTXO value (8 bytes)
sequence # This input's sequence (4 bytes)
hashOutputs # SHA256d of all outputs
locktime # 4 bytes
sighash_type # 4 bytes
))
This eliminates the O(n^2) scaling problem of legacy signing — where signing n inputs required hashing n copies of the entire transaction.
ECDSA Signature
Bitcoin uses ECDSA (Elliptic Curve Digital Signature Algorithm) on the secp256k1 curve. Given:
- A private key
d(256-bit integer) - A message hash
z(the signing digest)
The algorithm produces a signature (r, s) — two 256-bit integers that anyone can verify using the corresponding public key, but no one can forge without knowing d.
The signature is DER-encoded and appended with the SIGHASH byte:
30 <total-length>
02 <r-length> <r-value>
02 <s-length> <s-value>
<sighash-byte>
A typical DER-encoded signature is 71-73 bytes.
Low-S Requirement
BIP62 and BIP146 require that the s value be in the lower half of the curve order. If your ECDSA implementation produces a high-S value, you must replace it with order - s. Transactions with high-S signatures are rejected by modern nodes.
Putting It Into the Transaction
For a legacy input, the signature and public key go into the ScriptSig:
<sig-length> <DER-signature + sighash>
<pubkey-length> <compressed-public-key (33 bytes)>
For a SegWit input, the ScriptSig stays empty and the data goes into the witness field — covered next.
Next Step
Continue to SegWit and Witness Data to learn how SegWit transactions store signatures in the witness structure.