BIP62 - Dealing with Malleability¶
BIP62 (Bitcoin Improvement Proposal 62) is one of the Bitcoin improvement proposals, put forward by Pieter Wuille in 2014. It aimed to reduce or eliminate the transaction malleability problem by defining a series of rules. Although this proposal was ultimately never activated as a consensus rule, its analysis and solutions had a profound impact on the development of the Bitcoin protocol and laid the theoretical foundation for subsequent major upgrades such as Segregated Witness (BIP141).
Core Concept¶
Transaction Malleability refers to the issue where a transaction's ID (txid) can be modified before the transaction is confirmed. Although malleability attacks do not result in stolen funds, they can change the transaction's unique identifier, breaking subsequent transactions that depend on that ID. This creates serious problems for smart contracts, the Lightning Network, and other advanced applications.
BIP62 identified seven major sources of malleability and proposed corresponding restriction rules for each. These rules, by standardizing the transaction format, eliminate the ability of third parties to modify transaction IDs, keeping transactions stable from broadcast until confirmation.
Problem Background¶
What is Transaction Malleability¶
The transaction ID is the double SHA256 hash of the transaction content:
Malleability Problem: - Certain parts of a transaction can be modified without affecting its validity - The modified transaction is still valid, but the txid changes - Only one of the original and modified transactions can be confirmed - It is impossible to predict which version will be confirmed
Dangers of Malleability¶
1. Breaking Transaction Chains:
Scenario: Alice creates transaction A, Bob creates transaction B based on A
Step 1: Alice broadcasts transaction A (txid = 0x123...)
Step 2: Bob creates transaction B, referencing input 0x123...
Step 3: A third party modifies transaction A's signature, producing A' (txid = 0x456...)
Step 4: Transaction A' is confirmed instead of A
Step 5: Transaction B is invalidated because 0x123... does not exist
Result: Bob's transaction can never be confirmed
2. Fraudulent Claims of Non-Receipt:
Scenario: Alice withdraws from an exchange
Step 1: Exchange creates withdrawal transaction T1 (txid = 0xAAA...)
Step 2: Alice modifies T1 to T1' (txid = 0xBBB...)
Step 3: T1' is confirmed; Alice actually receives the funds
Step 4: Exchange queries 0xAAA... and finds it unconfirmed
Step 5: Alice claims she did not receive the funds and requests a re-withdrawal
Step 6: Exchange may be deceived and pays again
Result: Alice may receive double withdrawal (if the exchange system is flawed)
3. Hindering Layer 2 Development: - The Lightning Network needs to construct chains of unconfirmed transactions - Smart contracts need to know transaction IDs in advance - Atomic swaps need reliable transaction references - Malleability makes these applications unsafe or infeasible
Historical Events¶
2014 Mt. Gox Incident: - Mt. Gox, the largest Bitcoin exchange at the time, went bankrupt - Transaction malleability attacks were partly blamed - Users modified the txid of withdrawal transactions - Claimed non-receipt and obtained duplicate withdrawals - While malleability was not the sole cause of Mt. Gox's collapse, it exposed the severity of the problem
Sources of Malleability¶
BIP62 identified seven major sources of malleability:
1. Signature Malleability¶
Problem: ECDSA signatures are inherently malleable. For a signature (r, s), (r, -s mod n) is also a valid signature.
Example:
Original signature: (r, s)
Modified signature: (r, n - s) where n is the order of the elliptic curve
Both signatures pass verification but produce different txids
BIP62 Rule 1: Require signatures to use the low S value:
Implementation Status: - Partially addressed through BIP66 (strict DER signatures) - Became a standard transaction rule after Bitcoin Core 0.11.1 - SegWit in 2017 completely eliminated signature malleability
2. Non-DER Encoded Signatures¶
Problem: DER (Distinguished Encoding Rules) encoding allows multiple valid representations: - Length fields can have extra zeros - Integers can have leading zeros - Signatures can include extra padding
Example:
BIP62 Rule 2: Enforce strict DER encoding.
Implementation Status: - BIP66 activated in July 2015, enforcing strict DER - Became a consensus rule, fully resolving this issue
3. Extra Data in Scripts¶
Problem: Some script operations allow adding extra data without affecting execution:
Example:
Original script: <sig> <pubkey>
Modified script: <sig> OP_NOP <pubkey>
Or
Original script: OP_0
Modified script: OP_0 OP_0 OP_DROP
BIP62 Rule 3: Prohibit adding meaningless operations in scripts.
Implementation Status: - Partially implemented through standard transaction rules - SegWit fully resolved this by removing signature data
4. scriptPubKey Type Malleability¶
Problem: Certain output script types allow multiple representations:
Example:
Standard P2PK: <pubkey> OP_CHECKSIG
Alternative form: <pubkey> OP_NOP OP_CHECKSIG
Or
OP_0 can be written as OP_FALSE
OP_1 can be written as OP_TRUE
BIP62 Rule 4: Standardize scriptPubKey formats.
Implementation Status: - Partially implemented via IsStandard() checks - Restricted propagation of non-standard scripts
5. scriptSig Push Operations¶
Problem: Pushing data to the stack can use different opcodes:
Example:
Pushing 75 bytes of data:
Method 1: OP_PUSHDATA1 0x4b [75 bytes of data]
Method 2: 0x4b [75 bytes of data] <- minimal encoding
Pushing 0:
Method 1: OP_0
Method 2: OP_PUSHDATA1 0x00
Method 3: 0x00 <- empty byte string
BIP62 Rule 5: Require minimal push operations: - 0-75 bytes: direct push - 76-255 bytes: OP_PUSHDATA1 - 256-65535 bytes: OP_PUSHDATA2 - 65536+ bytes: OP_PUSHDATA4
Implementation Status: - Became a standard rule after Bitcoin Core 0.11.1 - Did not become a consensus rule (BIP62 was not activated)
6. Spurious Push Operations¶
Problem: scriptSig can contain data that is never used:
Example:
P2SH redeem script: 2 <pubkey1> <pubkey2> 2 OP_CHECKMULTISIG
Standard scriptSig: OP_0 <sig1> <sig2> <redeem script>
Modified scriptSig: OP_0 <sig1> <sig2> <extra data> OP_DROP <redeem script>
BIP62 Rule 6: Prohibit unused push operations in scriptSig.
Implementation Status: - Difficult to enforce without breaking compatibility - SegWit resolved this through the witness data structure
7. OP_CHECKMULTISIG Dummy Stack Element¶
Problem: Due to a historical bug, OP_CHECKMULTISIG pops one extra stack element:
Example:
2-of-3 multisig:
Normal: OP_0 <sig1> <sig2> | 2 <pk1> <pk2> <pk3> 3 OP_CHECKMULTISIG
Malleability modification:
OP_0 can be replaced with OP_1, OP_1NEGATE, or any data
as long as the element is popped
BIP62 Rule 7: Require the dummy stack element of OP_CHECKMULTISIG to be OP_0.
Implementation Status: - Standard rule since Bitcoin Core 0.10+ - BIP147 (activated 2017) made it a consensus rule
Technical Details¶
Strict DER Signatures (BIP66)¶
Strict rules for DER encoding:
Signature format:
0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash-type]
Strict requirements:
1. Total length must equal the actual length
2. R and S must be minimal-length encoded (no leading zeros, unless the high bit is 1)
3. R and S must be positive numbers
4. S must be <= n/2 (low S value)
5. sighash type must be defined (0x01, 0x02, 0x03, 0x81, etc.)
Low S Value Verification¶
def verify_low_s(signature):
"""Verify signature uses low S value"""
r, s = decode_signature(signature)
# Order of the secp256k1 curve
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
# Check s <= n/2
if s > n // 2:
return False
return True
Minimal Push Verification¶
def verify_minimal_push(opcode, data):
"""Verify minimal push operation is used"""
data_len = len(data)
if data_len == 0:
return opcode == OP_0
elif data_len == 1:
if 1 <= data[0] <= 16:
return opcode == OP_1 + (data[0] - 1)
elif data[0] == 0x81:
return opcode == OP_1NEGATE
else:
return opcode == 0x01
elif data_len <= 75:
return opcode == data_len
elif data_len <= 255:
return opcode == OP_PUSHDATA1
elif data_len <= 65535:
return opcode == OP_PUSHDATA2
else:
return opcode == OP_PUSHDATA4
The Fate of BIP62¶
Proposal Status¶
BIP62 underwent lengthy discussion after being proposed:
2014: Proposal published, identifying seven sources of malleability
2015: Some rules were adopted - BIP66 (strict DER) activated, addressing Rule 2 - Low S value became a standard rule
2016-2017: Plans for BIP62 as a soft fork were shelved - Technical challenges in full implementation were discovered - Some rules were difficult to enforce - The decision was made to fundamentally solve the problem through SegWit
Final Result: - BIP62 was never activated as a consensus rule - Marked as "Withdrawn" - But its analysis and some of its rules were still adopted
Why It Was Not Activated¶
Technical Challenges: - Rules 5 and 6 were difficult to enforce without breaking compatibility - Certain edge cases were complex to handle - Could affect the validity of existing scripts
A Better Solution: - SegWit (BIP141) provided a more thorough solution - By separating witness data, it completely eliminated third-party malleability - SegWit also brought other benefits (capacity increase, signature optimization, etc.)
Community Consensus: - In 2016, the community decided to focus on SegWit - SegWit could solve multiple problems at once - Avoided the complexity of multiple soft forks
Relationship with Other BIPs¶
BIP66 (Strict DER Signatures)¶
BIP66 implemented Rule 2 of BIP62: - Activated in July 2015 - Forced all signatures to use strict DER encoding - Eliminated DER encoding malleability
BIP141 (Segregated Witness)¶
SegWit thoroughly solved the malleability problem:
Before SegWit:
txid = SHA256(SHA256(version + inputs + outputs + locktime))
Inputs contain signature data; signatures can be modified -> txid is mutable
After SegWit:
txid = SHA256(SHA256(version + inputs (no signatures) + outputs + locktime))
Signatures are in witness data, do not affect txid -> txid is immutable
Complete elimination of third-party malleability: - Signature data no longer factors into txid - Third parties cannot modify txid - Only the transaction creator can modify the txid by changing the input script (which requires the private key)
BIP147 (OP_CHECKMULTISIG Dummy Element)¶
BIP147 implemented Rule 7 of BIP62: - Activated in August 2017, simultaneously with SegWit - Forced the OP_CHECKMULTISIG dummy element to be OP_0 - Further reduced malleability vectors
BIP143 (SegWit Signature Hash)¶
BIP143 defined a new signature algorithm for SegWit transactions: - Commits to input amounts during signing - Prevents certain types of malleability - Improves hardware wallet security
Implemented Rules¶
Although BIP62 as a whole was not activated, some rules were implemented through other means:
Standard Transaction Rules¶
Bitcoin Core implements the following rules as IsStandard() checks:
Low S Value (Rule 1): - Enforced since version 0.11.1 - Non-standard transactions are not relayed - But miners can still include them in blocks
Minimal Push (Rule 5): - Enforced since version 0.11.1 - Improved consistency of standard transactions
OP_CHECKMULTISIG Dummy Element (Rule 7): - Standard rule since version 0.10.0 - Upgraded to consensus rule via BIP147
Consensus Rules¶
BIP66 (Rule 2): - Strict DER encoding - Activated July 2015
BIP147 (Rule 7): - OP_CHECKMULTISIG dummy element must be OP_0 - Activated August 2017
Practical Impact¶
Impact on Users¶
Exchanges and Wallets: - Need to implement robust txid tracking mechanisms - Cannot rely solely on txid to determine whether a transaction is confirmed - Should verify inputs and outputs, not just the txid
Best Practices:
Poor approach:
if (txid == expected_txid) {
// Assume transaction confirmed
}
Correct approach:
if (transaction.inputs == expected_inputs &&
transaction.outputs == expected_outputs &&
transaction.confirmations >= 6) {
// Transaction confirmed and content correct
}
Impact on Developers¶
Unconfirmed Transaction Chains: - Before SegWit: Unsafe, should be avoided - After SegWit: Safe, making Lightning Network and similar applications possible
Smart Contracts: - Before SegWit: Contracts depending on txid were unsafe - After SegWit: Parent transactions can be safely referenced
Impact on the Ecosystem¶
Lightning Network: - Requires constructing chains of unconfirmed transactions - Malleability fix was a prerequisite - After SegWit activation, the Lightning Network developed rapidly
Atomic Swaps: - HTLCs require reliable txids - Malleability fix made cross-chain atomic swaps possible
Security Considerations¶
Developer Guidelines¶
1. Do Not Rely Solely on txid:
# Incorrect example
def check_payment(expected_txid):
tx = blockchain.get_transaction(expected_txid)
return tx.confirmed
# Correct example
def check_payment(expected_address, expected_amount):
txs = blockchain.get_transactions_to(expected_address)
for tx in txs:
if tx.amount == expected_amount and tx.confirmations >= 6:
return True
return False
2. Use SegWit Addresses: - Prefer native SegWit (bc1q...) - Or nested SegWit (starting with 3...) - Completely avoids third-party malleability
3. Monitor All Transaction Versions: - Track all transactions spending the same inputs - Identify which version is confirmed - Update internal records promptly
Exchange Security¶
Withdrawal Systems:
1. Create withdrawal transaction T
2. Record the transaction's inputs and outputs, not just the txid
3. Broadcast the transaction
4. Monitor the blockchain for transactions matching the inputs/outputs
5. Upon confirmation, regardless of whether the txid matches, mark as complete
6. Do not respond to "txid not confirmed" complaints (verify inputs/outputs)
Double-Spend Detection: - Monitor all transactions spending the same UTXO - Distinguish between malleability modifications and genuine double-spends - Treat differently and take appropriate measures
Comparison: BIP62 vs SegWit¶
| Feature | BIP62 | SegWit (BIP141) |
|---|---|---|
| Solves Malleability | Partially (seven rules) | Completely (third-party malleability) |
| Implementation Complexity | High (multiple independent rules) | Medium (unified architecture) |
| Other Benefits | None | Capacity increase, signature optimization |
| Activation Status | Not activated (withdrawn) | Activated (2017) |
| Backward Compatibility | Soft fork | Soft fork |
| Community Support | Divided | Eventually reached consensus |
| Lightning Network Support | Insufficient | Full support |
| Smart Contract Impact | Partial improvement | Fundamental solution |
Historical Significance¶
BIP62's Contributions¶
Despite not being activated, BIP62 remains important:
Theoretical Foundation: - Systematically analyzed the malleability problem - Identified all major sources of malleability - Provided a framework for subsequent solutions
Partial Implementation: - Low S value became a standard rule - Strict DER implemented through BIP66 - OP_CHECKMULTISIG fix implemented through BIP147
Driving SegWit: - The challenges of BIP62 prompted the community to seek a better solution - SegWit emerged as a comprehensive solution - Solved malleability and other problems in one go
Lessons Learned¶
1. Complex Problems Need Comprehensive Solutions: - Patching malleability sources one by one was inefficient - SegWit solved the problem once and for all through an architectural change - Avoided the risk of multiple soft forks
2. Standard Rules vs. Consensus Rules: - Standard rules can iterate quickly - Consensus rules require caution and thorough testing - Both working together can achieve gradual improvement
3. Importance of Community Coordination: - Technical solutions require community consensus - Trade-offs between multiple small upgrades vs. one large upgrade - Thorough discussion prevented wrong directions
Summary¶
BIP62 is an important proposal in Bitcoin history. Although it was ultimately not activated, its influence has been profound:
Core Contributions: - Systematic analysis: First comprehensive identification of seven malleability sources - Theoretical foundation: Provided a framework for solving the malleability problem - Partial implementation: Partially addressed the problem through standard rules and other BIPs - Driving innovation: Prompted the community to develop the superior SegWit solution
Practical Value: - Strict DER (BIP66) eliminated signature encoding malleability - Low S value rule reduced signature malleability - OP_CHECKMULTISIG fix (BIP147) eliminated multisig malleability - Paved the way for SegWit's design and activation
Historical Significance: - Demonstrated the Bitcoin community's technical depth and iterative capability - Proved that sometimes a "better solution" is worth waiting for - The evolution from BIP62 to SegWit is a model of Bitcoin's gradual improvement - Cleared obstacles for revolutionary technologies like the Lightning Network
Final Outcome: Although BIP62 was never activated as an independent soft fork, the problems it identified have been thoroughly resolved through SegWit (BIP141). SegWit not only eliminated third-party malleability but also brought additional benefits such as capacity increase and signature optimization. In a sense, BIP62's "failure" was actually a success in the Bitcoin protocol evolution process -- through thorough discussion and technical exploration, the community found a superior solution.
Today, with widespread SegWit adoption, transaction malleability is no longer a major issue for Bitcoin. Advanced applications that depend on stable txids -- such as the Lightning Network, smart contracts, and atomic swaps -- are flourishing. BIP62's analysis and exploration, and the process of being ultimately superseded by SegWit, perfectly illustrate Bitcoin's evolution philosophy as an open-source protocol: continuous experimentation, thorough discussion, selecting the best approach, and ongoing improvement.