When a segwit input is signed, the signature will commit to the witness script (or a p2pkh-like script in case of p2wpkh). This is specified in BIP143:
P2WPKHwitness program, the
- if the
witnessScriptdoes not contain any
witnessScriptserialized as scripts inside
- if the
witnessScriptbut removing everything up to and including the last executed
OP_CODESEPARATORbefore the signature checking opcode being executed, serialized as scripts inside
CTxOut. (The exact semantics is demonstrated in the examples below)
What's the rationale behind this? Why doesn't the hash commit to the pubkey script as in legacy (p2pkh and p2sh) payments? This difference complicates signing/verification code a bit, so I suppose there must be some good reason for it.
Maybe my question should be: Why does the hash commit to any script at all for segwit inputs? In legacy signatures, putting scriptPubkey in scriptSig for the current input is a (complicated, see below) way to avoid signature reuse between inputs. But in segwit, this is accomplished with the
outpoint part of the hashing algorithm. So couldn't we just skip the
It seems to me that there is another reason for why we hash the scriptPubkey for legacy signatures and the witness script for segwit signatures, since there are simpler ways to avoid signature reuse:
- Legacy: We could just have added a dummy byte somewhere in the current input
- Segwit: Current input's outpoint already solves the problem.