shuijian-xu / bitcoin

0 stars 0 forks source link

Transaction Malleability #229

Open shuijian-xu opened 4 years ago

shuijian-xu commented 4 years ago

Transaction malleability is the ability to change the transaction’s ID without altering the transaction’s meaning.

shuijian-xu commented 4 years ago

This is not usually a problem as once a transaction enters the blockchain, the transaction ID is fixed and no longer malleable (at least without finding a proof-of-work!). However, with payment channels, there are dependent transactions created before the funding transaction is added to the blockchain.

shuijian-xu commented 4 years ago

The one field that does allow for some manipulation without invalidating the signature is the ScriptSig field on each input. The ScriptSig is emptied before creating the signature hash (see Chapter 7), so it’s possible to change the ScriptSig without invalidating the signature. Also, as we learned in Chapter 3, signatures contain a random component. This means that two different ScriptSigs can essentially mean the same thing but be different byte-wise.

This makes the ScriptSig field malleable—that is, able to be changed without changing the meaning—and means that the entire transaction, and the transaction ID, are malleable. A malleable transaction ID means that any dependent transactions (that is, any transaction spending one of the malleable transaction’s outputs) cannot be constructed in such a way as to guarantee validity. The previous transaction hash is uncertain, so the dependent transaction’s transaction input field cannot be guaranteed to be valid.

shuijian-xu commented 4 years ago

Transaction malleability is fixed by emptying the ScriptSig field and putting the data in another field that’s not used for ID calculation. For p2wpkh, the signature and pubkey are the items from ScriptSig, so those get moved to the witness field, which is not used for ID calculation. This way, the transaction ID stays stable as the malleability vector disappears. The witness field, and the whole Segwit serialization of a transaction, is only sent to nodes that ask for it. In other words, old nodes that haven’t upgraded to Segwit don’t receive the witness field and don’t verify the pubkey and signature.