<p><code>OP_CODESEPARATOR</code> 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.</p>

<p>For more details on the potential attack vectors it resulted in, see</p>

<p><a href="https://bitcointalk.org/index.php?topic=255145.msg2757327" rel="nofollow noreferrer">https://bitcointalk.org/index.php?topic=255145.msg2757327</a></p>

CC BY-SA 3.0
2017-08-14T17:46:33.630Z
2017-08-14T17:46:33.630Z
almel
<p>Looking at <a href="https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png" rel="noreferrer">this diagram of OP_CHECKSIG steps</a> and the <a href="https://en.bitcoin.it/wiki/Script" rel="noreferrer">Bitcoin Script wiki</a>, OP_CODESEPARATOR is used to make OP_CHECKSIG check only <em>part</em> 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. </p>

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

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

<p>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 <a href="http://sourceforge.net/p/bitcoin/mailman/message/29593157/" rel="noreferrer">this</a>, <a href="https://github.com/bitcoin/bips/blob/master/bip-0017.mediawiki" rel="noreferrer">this</a> and <a href="https://bitcointalk.org/index.php?topic=164655.0" rel="noreferrer">this</a> (and the thread you referenced) for core developers commenting on or discussing possible uses for OP_CODESEPARATOR.</p>

CC BY-SA 3.0
2014-12-25T17:39:59.953Z
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
CC BY-SA 3.0
2014-12-26T01:44:29.030Z
I can't be certain, but it looks like based on the bitcoind tests [here](https://github.com/bitcoin/bitcoin/blob/886eb57507eb8ec657bc67320eec6374fe37806e/src/test/data/tx_valid.json#L152-L154) that OP_CODESEPARATOR within IF statements *shouldn't* be evaluated as the last OP_CODESEPARATOR if the IF condition is false.
soroushjp
CC BY-SA 3.0
2014-12-26T01:47:55.120Z
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
CC BY-SA 3.0
2014-12-26T02:04:18.170Z
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
CC BY-SA 3.0
2014-12-25T14:44:17.713Z
2014-12-25T14:44:17.713Z
soroushjp
<p>Looking at the Bitcoin source (<a href="https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/script.cpp#L843-L847" rel="nofollow noreferrer">https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/script.cpp#L843-L847</a>, specifically), I ran into the use of the <code>OP_CODESEPARATOR</code>. 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 <code>OP_CODESEPARATOR</code>? What happens if an <code>OP_IF</code> causes an <code>OP_CODESEPARATOR</code> to be skipped?</p>
<p>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?</p>
<p>I've read through <a href="https://bitcointalk.org/index.php?topic=52949.0" rel="nofollow noreferrer">this bitcointalk thread</a>, but didn't really find any conclusion there.</p>

CC BY-SA 3.0
2014-12-13T03:19:24.907Z
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
<script><bitcoin-core-development>
What is OP_CODESEPARATOR used for?
morsecoder
# What is OP_CODESEPARATOR used for?

(Asked by: username_0 on 2014-12-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](https://bitcointalk.org/index.php?topic=52949.0), but didn't really find any conclusion there.

**Tags:** script, bitcoin-core-development

> **Comments:**
> **username_1**: 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. ;)  

---

## 2 answers

### Answer by username_3 on 2014-12-25. Score: 8 | Accepted answer

Looking at [this diagram of OP\_CHECKSIG steps](https://en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png) and the [Bitcoin Script wiki](https://en.bitcoin.it/wiki/Script), 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](http://sourceforge.net/p/bitcoin/mailman/message/29593157/), [this](https://github.com/bitcoin/bips/blob/master/bip-0017.mediawiki) and [this](https://bitcointalk.org/index.php?topic=164655.0) (and the thread you referenced) for core developers commenting on or discussing possible uses for OP\_CODESEPARATOR.

> **Comments:**
> **username_0**: 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?  
> **username_3**: I can't be certain, but it looks like based on the bitcoind tests [here](https://github.com/bitcoin/bitcoin/blob/886eb57507eb8ec657bc67320eec6374fe37806e/src/test/data/tx_valid.json#L152-L154) that OP_CODESEPARATOR within IF statements *shouldn't* be evaluated as the last OP_CODESEPARATOR if the IF condition is false.  
> **username_0**: 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.  
> **username_3**: 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.  

---

### Answer by username_2 on 2017-08-14. Score: 3

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


---

