Hardfork suggestion: how to fix transaction malleability
We can introduce another version of transactions (2) that will change how signatures are verified and stored within the transaction.
The malleability of transactions stems from the fact that we store signatures in the input scripts and for purposes of signing and verifying the signature, all input scripts are completely stripped. This allows anyone to introduce non-breaking changes to the input scripts that keep signatures correct, but change the whole transaction hash.
To fix that, we add a level of indirection. All signatures will be stored in a separate location in the transaction, ordered. Input scripts will only reference the index of the signature and never be stripped for the purposes of signing.
Input scripts are not stripped during SignatureHash phase.
CHECKSIG and CHECKMULTISIG expect not a signature, but a “signature index”, as PUSHDATA (does not need to be normalized).
Signatures are listed in an array in the tail of the transaction (after lock time). All length prefixes must be normalized in that array (including length prefix of the array itself).
All signatures must be canonical.
When signing an input, its script is appended with the output script (today output script replaces the input script).
When verifying the signature, storage of signatures is stripped off completely (“signatures cannot sign themselves”).
Transaction ID remains the same: a double-SHA256 of the entire transaction, so no changes in the transaction inputs or merkle trees is needed.
Old versions of transactions are still malleable and can be created by older clients and will always be valid. New versions will be accepted by the network if network decides so with a majority vote. There will be an announced block height starting with which version 2 transactions will be valid.
How to vote?
Miners may express their support by mentioning “/CTv2/” (“Canonical transactions AKA version 2”) in their coinbase.
But before that, miners must see that most used software is upgraded to support validation of “version 2” transactions. I.e. bitcoind, libbitcoin, bitcoin-ruby, Multibit, Electrum, mobile apps if needed.
If after block height N, more than 95% of blocks in the past 10000 blocks are supporting the change, network starts accepting transactions with version 2 and new signature check rules in those transactions.
Then, if your special scheme (like rapidly-adjusted micropayments) requires reference to an unconfirmed transaction, you would simply require using a version 2 transaction and have guarantee that its ID can’t be changed.
EDIT: as Luke-Jr suggested, in the future we may want some other data to be stripped for signing purposes (e.g. if we implement other signature schemes with new or existing opcodes). To support that, we may allow any “pushdata” to be “indirect” or “strippable”. Maybe with some extra opcode acting as a prefix before pushdata. E.g. OP_NOP1 will be used as OP_STRIP and mean “for signature hash”, strip the following piece of data.
