13

Looking at the Bitcoin source (https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/script.cpp#L843-L847, specifically), I ran into the use of the OP_CODESEPARATOR. Am I right in interpreting this code that it is not always the case that the whole scriptPubKey is signed, but really just the part that is later than the most recent OP_CODESEPARATOR? What happens if an OP_IF causes an OP_CODESEPARATOR to be skipped?

It seems strange to me that the entire scriptPubKey isn't used for signing in all cases, so I'm guessing there is some use case for this that I haven't thought of. Does anyone know what this use case is?

I've read through this bitcointalk thread, but didn't really find any conclusion there.

1
  • 5
    The really telling thing about the usefulness of OP_CODESEPARATOR is that all of the results in Google are people asking what it's used for. ;)
    – Nick ODell
    Commented Dec 13, 2014 at 3:19

2 Answers 2

8

Looking at this diagram of OP_CHECKSIG steps and the Bitcoin Script wiki, OP_CODESEPARATOR is used to make OP_CHECKSIG check only part of the scriptPubKey. Essentially, only the script that goes after the last OP_CODESEPARATOR is used to sign the transaction and hence evaluated by OP_CHECKSIG.

In theory, a spending transaction could change the part of the scriptPubKey before the last OP_CODESEPARATOR of the input transaction.

However, there's a problem. Since scriptPubKey comes from the input transaction, you can't actually modify any part of the scriptPubKey (even the part before the last OP_CODESEPARATOR) without changing the input transaction hash. Changing the input transaction hash breaks the link for any transaction trying to spend outputs from the unspent input transaction, making it impossible to use OP_CODESEPARATOR in practice.

I wasn't able to find any cases in practice where people have successfully used OP_CODESEPARATOR for a useful purpose, although it does show up in the blockchain. See this, this and this (and the thread you referenced) for core developers commenting on or discussing possible uses for OP_CODESEPARATOR.

4
  • What happens in the script evaluation if the OP_CODESEPARATOR is inside of an if else block? Does the part being signed always go right to the end of the scriptPubKey?
    – morsecoder
    Commented Dec 25, 2014 at 17:39
  • I can't be certain, but it looks like based on the bitcoind tests here that OP_CODESEPARATOR within IF statements shouldn't be evaluated as the last OP_CODESEPARATOR if the IF condition is false.
    – soroushjp
    Commented Dec 26, 2014 at 1:44
  • But it will allow everything in the else block to be signed, in that case, which seems strange. Haven't looked at the links you sent yet, but can't envision a case where the OP is useful yet, even if it were possible to use... Thanks for your answers.
    – morsecoder
    Commented Dec 26, 2014 at 1:47
  • I think it would sign everything after the last OP_CODESEPARATOR, so unless there was a OP_CODESEPARATOR in the ELSE block, everything would be signed. But yes agreed, can't find a useful case yet, especially with the problem of the input tx hash changing. If you find one, please post it here for the community. Great question @StephenM347.
    – soroushjp
    Commented Dec 26, 2014 at 2:04
2

OP_CODESEPARATOR is a leftover opcode from a previous version of the scripting language and was found to contain pretty dreadful bugs; it is no longer used in Bitcoin scripts, and except for probably some very low-level edge-cases safely ignore its existence.

For more details on the potential attack vectors it resulted in, see

https://bitcointalk.org/index.php?topic=255145.msg2757327

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.