14 - SIGHASH flags

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

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.

SIGHASH_ALL, SIGHASH_SINGLE, SIGHASH_NONE

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

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.

Example: Checking SIGHASH flags

Stack
Script
Description

<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.

Last updated

Was this helpful?