OP CHECKSIG
OP_CHECKSIG is script opcode used to verify that the signature for a tx input is valid. OP_CHECKSIG expects two values to be on the stack, these are, in order of stack depth, the public key and the signature of the script. These two values are normally obtained by running the scriptSig script of the transaction input we are attempting to validate. After the scriptSig script is run the script is deleted but the stack is left as is, and then then scriptPubKey script from the previous transaction output that is now being spent is run, generally concluding in an OP_CHECKSIG.
The standard scriptPubKey checks that the public key (actually a hash of) is a particular value, and that OP_CHECKSIG passes.
For normal transaction inputs if the creator of the current transaction can successfully create a ScriptSig signature that uses the right public key for the ScriptPubKey of the transaction output they are attempting to spend, that transaction input is considered valid.
Parameters
In addition to the script code itself and the stack parameters, to operate OP_CHECKSIG needs to know the current transaction, the current transaction input, and the current hashtype (discussed later)
How it works
- the public key and the signature are popped from the stack, in that order.
- A new subscript is created from the instruction from the most recent OP_CODESEPARATOR to the end of the script. If there is no OP_CODESEPARATOR the entire script becomes the subscript (hereby referred to as subScript)
- The sig is deleted from subScript.
- The hashtype is removed from the last byte of the sig and stored
- A deep copy is made of the current transaction (hereby referred to txCopy)
- All OP_CODESEPARATORS are removed from subScript
- The scripts for all transaction inputs in txCopy are set to empty scripts
- The script for the current transaction input in txCopy is set to subScript
Now depending on the hashtype various things can happen to txCopy, these will be discussed individually
Hashtype Values (from script.h):
Name | Value |
---|---|
SIGHASH_ALL | 0x00000001 |
SIGHASH_NONE | 0x00000002 |
SIGHASH_SINGLE | 0x00000003 |
SIGHASH_ANYONECANPAY | 0x0000000080 |
Hashtype SIGHASH_ALL (default)
No special handling occurs in the default case
Hashtype SIGHASH_NONE
- The output of txCopy is set to a vector of zero size.
- All other inputs aside from the current input in txCopy have their nSequence index set to zero
Hashtype SIGHASH_SINGLE
- The output of txCopy is resized to the size of the current input index+1
- All other txCopy outputs aside from the output that is the same as the current input index are set to a blank script and a value of (long) -1;
- All other txCopy inputs aside from the current input are set to have an nSequence index of zero
Hashtype SIGHASH_ANYONECANPAY
- The txCopy input vector is resized to a length of one
- The current input is set as the first and only member of this vector
Final signature
An array of bytes is constructed from the serialized txCopy + four bytes for the hash type. This array is sha256 hashed twice, then the public key is used to to check the supplied signature against the hash.
Return values
OP_CHECKSIG will push true to the stack if the check passed, false otherwise. OP_CHECKSIG_VERIFY leaves nothing on the stack but will cause the script eval to fail immediately if the check does not pass.