14 - SIGHASH flags
Last updated
Was this helpful?
Last updated
Was this helpful?
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.