Author

Topic: Why TxPrev.PkScript is inserted into TxCopy during signature check? (Read 3661 times)

legendary
Activity: 1120
Merit: 1152
(the actual v0.1 release inserted OP_CODESEPARATOR explicitly prior to calling EvalScript, breaking the idea, so I'm not sure if Satoshi actually realized what could have been made possible)

It seems so needlessly complicated that it must have had a reason. I wonder if maybe he intended to add a 'sticky' flag that required conditions on an output to be concatenated onto any new outputs it was spent to. The whole thing is very confusing to me though, and I'm having great trouble understanding your post.

It's confusing to me too; I didn't clue into the soft-fork stuff until about the third or fourth time I looked at that code.

Keep in mind Bitcoin had pretty poor software engineering in v0.1, so finding features that turned out to be poorly thought through shouldn't be surprising.
hero member
Activity: 714
Merit: 500
Martijn Meijering
(the actual v0.1 release inserted OP_CODESEPARATOR explicitly prior to calling EvalScript, breaking the idea, so I'm not sure if Satoshi actually realized what could have been made possible)

It seems so needlessly complicated that it must have had a reason. I wonder if maybe he intended to add a 'sticky' flag that required conditions on an output to be concatenated onto any new outputs it was spent to. The whole thing is very confusing to me though, and I'm having great trouble understanding your post.
legendary
Activity: 1120
Merit: 1152
I think that the point is to "mark" the transaction input that is being signed to prevent one signature to be used for more than one input.

Doesn't the signature already apply to the hash of the previous transaction and the index in it? Why would you need any additional data at all?

Bitcoin prior to the v0.1 release had a system where the scriptSig and scriptPubKey were concatenated prior to evaluation; OP_CODESEPARATOR was included in scripts (or scriptSigs) explicitly to mark what part of that concatenated script was to be hashed. The mechanism was broken because OP_RETURN could be used in a scriptSig to return prematurely, but other than that oversight the idea was sound. (the actual v0.1 release inserted OP_CODESEPARATOR explicitly prior to calling EvalScript, breaking the idea, so I'm not sure if Satoshi actually realized what could have been made possible)

Inserting this script into the txcopy scriptSig was the mechanism by which items in the scriptSig could be included in the signature. Something interesting about SignatureHash is you can use non-standard hashtypes in a backwards compatible way: nHashType is ANDed with mask 0x1f, or 0b00011111, prior to testing against SIGHASH_SINGLE and SIGHASH_NONE, which means that if they are set to anything other than those two values the signature hash is calculated without modifying vout. Similarly bits 6 and 7 of nHashType are completely ignored. Had the original design been kept additional SignatureHash() flags could have easily and efficiently been added in a soft-fork, for instance:

scriptPubKey: OP_CHECKSIG
scriptSig:

OP_CHECKSIG has defunct code to remove the signature from the concatenated script prior to calling SignatureHash(), so the final concatenated script inserted into the txin scriptSig would be:

OP_CHECKSIG

That additional hashed data could have be, for instance, the hash of the values going into the transaction to allow for signatures to cover fees. Similarly it could have been used with SIGHASH_NONE to redefine how signatures worked. Though note that for this to be a soft fork failure to match that additional data would have to be handled with as an immediate fail, turning OP_CHECKSIG into OP_CHECKSIGVERIFY with respect to the new features.

Having said that we can still do this, although it gets less efficient. Basically you just make an entire second signature, ~72 bytes worth, and have the special signature hash bits trigger the OP_CHECKSIG code to check it as well. For instance:

scriptPubKey: OP_CHECKSIG
scriptSig:

Where sig1 uses the old signature algorithm, and sig2 uses a new algorithm. For pre-soft-fork nodes sig2 is just useless data and does nothing, but for post-soft-fork nodes if sig2 is invalid the transaction fails.
hero member
Activity: 714
Merit: 500
Martijn Meijering
I think that the point is to "mark" the transaction input that is being signed to prevent one signature to be used for more than one input.

Doesn't the signature already apply to the hash of the previous transaction and the index in it? Why would you need any additional data at all?
legendary
Activity: 2128
Merit: 1073
Very interesting software archeology Smiley
Like a part of DNA of an extinguished specimen that got trapped in the DNA of Bitcoin.
Very wise statement. Bitcoin is like amber, the bugs inside are to be admired for their beauty as long as possible.
https://bitcointalksearch.org/topic/m.556688
hero member
Activity: 555
Merit: 654
Very interesting software archeology Smiley

Like a part of DNA of an extinguished specimen that got trapped in the DNA of Bitcoin.

legendary
Activity: 1526
Merit: 1134
I suspect this is left over from the first release of Bitcoin which had a broken way of running scripts - they were literally concatenated with an OP_CODESEPARATOR which meant you could steal anyones money by crafting a custom transaction. It may have been cruft left over from development at that point.
legendary
Activity: 1072
Merit: 1181
Why  TxPrev.PkScript is inserted into TxCopy ?

Ask Satoshi...

(I suspect the answer is that it felt safer to him for some subjective and not very well-founded reason)
hero member
Activity: 555
Merit: 654
In the https://en.bitcoin.it/wiki/OP_CHECKSIG wiki, the process behind OP_CHECKSIG is described.

Why  TxPrev.PkScript is inserted into TxCopy ?
(In the source code the method is called SignatureHash() and the temporary tx is TxTmp not TxCopy, and the input is nIn.)

I think that the point is to "mark" the transaction input that is being signed to prevent one signature to be used for more than one input.
But why not only insert a single char '*' into the script of input nIn ? Why a big chunk of the  TxPrev.PkScript is inserted ?

What is the functionality I'm missing?

Thanks, Sergio.







Jump to: