14 - SIGHASH flags
Last updated
Last updated
The Sighash flags determine which parts of the transaction are being signed.
This value impacts other elements of the pre-image including hashPrevouts, hashSequence and hashOutputs. The SIGHASH flags are all contained within the last single byte of a signature, however in the pre-image they are contained within a 4 byte value, where the left-most byte is the SIGHASH flag applied to the signature, and the remaining 3 bytes are zero.
Sighash flags work as follows:
SIGHASH_ANYONECANPAY determines which of the transaction inputs the signature covers.
If SIGHASH_ANYONECANPAY is not set, the signature must include all of the transaction inputs in the hash_nSequence and hash_prevouts values.
If SIGHASH_ANYONECANPAY is set, only the input that the signature is applied to needs to be included. Because the previous output and nSequence are handled otherwise, both hash_nSequence and hash_prevouts are set to 32byte null strings when SIGHASH_ANYONECANPAY is set. SIGHASH_ANYONECANPAY can be useful when signing an input in advance of other transaction participants, where other inputs may be unknown.
Only one of SIGHASH_ALL, SIGHASH_SINGLE and SIGHASH_NONE can be used in any signature. If more than one of these flags is set, the transaction will be invalid.
If SIGHASH_ALL is used, the signature must include all of the transaction outputs when it builds the pre-image.
If SIGHASH_SINGLE is used, the signature must include only the transaction output at the same index as the input being signed in the pre-image.
If SIGHASH_NONE is used, none of the transaction's outputs are included in the pre-image.
SIGHASH_FORKID is a flag that was added to the signatures after August 1 2017 to provide replay protection against the BTC network when it was separated from Bitcoin to add segregated witness. SIGHASH_FORKID must ALWAYS be set, or the transactions will be invalid.
<r_tx_preimg>
...
Because nSequence is the final 4 byte value, we do not need to know what parts of r_tx_preimg remain to be able to extract it.
<r_tx_preimg>
OP_SIZE
Put the size of r_tx_preimg on the stack
<r_tx_preimg> <size>
OP_4
SIGHASH length is 4 bytes long
<r_tx_preimg> <size> 0x04
OP_SUB
Calculate split location
<r_tx_preimg> <split_length>
OP_SPLIT
Split the pre-image
<lr_tx_preimg> <sighash>
OP_NIP
Remove remainder
<sighash>
<required_sighash>
Load the required sighash flag onto the stack as a 1 byte value
<sighash> <required_sighash>
OP_NUMEQUALVERIFY
Use numeric equality check to validate that the correct sighash is used.
...
...
rest of script
In this script, we first use OP_SIZE to push the length of r_tx_preimg to the stack. By subtracting 4 from this, we can calculate the location in the remaining pre-image where the sighash element begins, and use that value to split it from r_tx_preimg. Once sighash is on the stack, it is a simple numeric equality check against a supplied sighash.
Alternative scenarios include using a bitwise mask and performing AND/OR checks against individual flags rather than enforcing the entire sighash state.