OP_CODESEPARATOR is arguably the most mysterious opcode in Bitcoin Script. We give an introduction to it and demonstrate its usage in a practical application: optimizing preimage size in OP_PUSH_TX.
OP_CODESEPARATOR
Sighash preimage is what gets signed in a Bitcoin signature, whose format is as follows:
Part 5, scriptCode, usually contains the entire locking script. The only exception is when there is OP_CODESEPARATOR (OCS) in it. In this case, the scriptCode is the locking script but removing everything up to and including the last executed OCS before OP_CHECKSIG is executed.
OCS in sCrypt
We have added OCS support in sCrypt. Three or more *
in a line inserts an OCS. We have shown two OCSs in the example below: first represented by 3 asterisks, second 5.
We have also added support in our SDK and IDE since v1.4.1.
Use Case: Optimizing OP_PUSH_TX
In many cases, scriptCode, or portion of it, is not needed when using OP_PUSH_TX. OCS can be used to cut its size. For example, in the following contract, only part 9, nLocktime, of the whole preimage is needed. We use Tx.checkPreimageOCS(), a variant of the conventional Tx.checkPreimage(). The only difference is that an OCS is inserted right before OP_CHECKSIG within the former. Also note we put Tx.checkPreimageOCS() as the last statement for maximal optimization.
After the change, the preimage size is cut from 915 to 201 bytes, a significant savings of ~80%.
Summary
We have demonstrated the first widely applicable usage of OCS. Other potential usages include in-script functions and signing different execution paths in off-chain transactions.