transactions – That means of “Drop the signature” feedback in OP_CHECKSIG code (Bitcoin v0.1.0)

0
68


You’re right that the signature wouldn’t truly be current in that hash because of the OP_CODESEPARATOR used. Take into account that v0.1.0 was very unpolished code and had plenty of bugs and bizarre behaviour. Not the whole lot is sensible.

To clarify for those who need extra context, by the point we attain EvalScript(), the script shall be of the shape:

txin.scriptSig + OP_CODESEPARATOR + txout.scriptPubKey

the place txin.scriptSig is from the spending transaction enter, and can comprise the signature, and txout.scriptPubKey is from the earlier transaction UTXO being spent and can comprise the general public key and OP_CHECKSIG opcode. That is precisely what’s written within the query.

Ranging from the start, the signature shall be pushed onto the analysis stack, then we’ll hit the OP_CODESEPARATOR so pbegincodehash shall be up to date to that time within the script, then the general public key shall be pushed onto the analysis stack, and eventually the OP_CHECKSIG is reached.

Precisely as you say, the signature and public key will then be taken off the stack in reverse order and saved in vchSig and vchPubKey respectively.

scriptCode is then set to the subscript beginning at pbegincodehash till the tip of the script. On this case, it begins on the OP_CHECKSIG we encountered beforehand, so scriptCode will merely comprise the general public key push and the OP_CHECKSIG opcode.

Thus, when scriptCode.FindAndDelete(CScript(vchSig)) is known as, it does nothing on this case as a result of vchSig is just not a part of scriptCode.

Nevertheless, for the context of why deleting the signature from the script is necessary for verifying the signatures, let’s look a bit additional. CheckSig() is known as with the signature (vchSig), the general public key (vchPubKey), and the scriptCode:

CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)

which then calls

SignatureHash(scriptCode, txTo, nIn, nHashType)

to generate the hash of the message. The hash is generated by deleting all remaining OP_CODESEPARATORs from the script, setting the scriptSig of all the opposite inputs to the spending transaction to empty, units the scriptSig of the present enter being signed to scriptCode, after which (ignoring the opposite signing sorts) serialises the transaction and hashes it.

Recall that to confirm a signature we’d like the message (which is then hashed), the general public key, and the signature itself. The message must be in precisely the identical type as what was initially signed. That’s the reason we’ve got to delete the signature itself from the transaction being signed, as a result of it clearly could not have been current at signal time. Nevertheless, on this case, it does nothing, as a result of there are not any signatures after OP_CODESEPARATOR anyway. The clearing of scriptSigs within the SignatureHash() operate is extra necessary right here as a result of they’d all be empty at signing time.

To examine this, we will check out the SignSignature() operate too, which truly generates the signatures. We will see that it passes scriptPrereq + txout.scriptPubKey to the SignatureHash() operate above because the scriptCode. scriptPrereq is at all times empty on this code. So mainly scriptCode is at all times simply the scriptPubKey. That matches precisely what we count on.

LEAVE A REPLY

Please enter your comment!
Please enter your name here