Difference between revisions of "OP CODESEPARATOR"

m
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
OP_CODESEPARATOR is an opcode used in the script evaluation engine to determine what parts of a script must be hashed to create the message used when creating [[Digital Signatures (ECDSA)]] for Bitcoin transactions. The opcode is inserted automatically between the ScriptSig and ScriptPubKey prior to the evaluation taking place, however further instances of OP_CODESEPARATOR can be inserted into scripts to removing prior script sections from the message. This can allow transactions with multiple signatures to be built additively.
+
OP_CODESEPARATOR was originally designed to be inserted between the ScriptPubKey and ScriptSig by the script evaluation engine. When OP_CHECKSIG is called in the ScriptPubKey, it will remove everything before OP_CODESEPARATOR. In the default case, the entire ScriptSig will be removed as the ScriptSig containing the signature cannot be signed by the signature.  
  
==Example 1==
+
There is no rule to prevent users from inserting OP_CODESEPARATOR into the ScriptPubKey however OP_CODESEPARATOR will only be effective if it is read by OP_CHECKSIG in the same ScriptPubKey. OP_CHECKSIG will read back to the closest OP_CODESEPARATOR before it and remove all message contents before that.
The following is a basic [[Bitcoin Transactions#Pay to Public Key|P2PKH]] script:
 
  
{| class="wikitable"
+
==Example==
|-
+
Based on the understanding above, we can construct the following ScriptPubKey:
! ScriptSig
 
! Auto inserted OCS
 
! ScriptPubKey
 
|-
 
| SIG1 PK1
 
| OP_CODESEPARATOR
 
| OP_DUP OP_HASH160 <pkh1> OP_EQUALVERIFY OP_CHECKSIG
 
|}
 
  
The OP_CODESEPARATOR is added between the ScriptSig and ScriptPubKey by the script interpreter so that it can determine what part of the message must be checked against the signature. Everything that follows the OP_CODESEPARATOR is included in the message hash.
+
<code>OP_CODESEPARATOR OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIG</code>
  
==Example 2==
+
To unlock this ScriptPubKey, we can use the following ScriptSig:
This next example shows a more complex script with an addition OP_CODESEPARATOR which separates [[Bitcoin Transactions#Pay to Public Key Hash|public key hash check]] and an [[Bitcoin Transactions#Pay to R-Puzzle Hash|R-Puzzle]]:
+
 
{| class="wikitable"
+
<code><Sig A> <PK A> <Sig B> <PK B> <Sig C> <PK C></code>
|-
+
 
! ScriptSig part 2
+
Note that the first OP_CHECKSIG will verify <Sig C> <PK C> on the following message:
! ScriptSig part 1
+
 
! Auto inserted OCS
+
<code>OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIG</code>
! ScriptPubKey part 1
+
 
! OCS
+
The second OP_CHECKSIG will verify <Sig B> <PK B> on the following message:
! ScriptPubKey part 2
+
 
|-
+
<code>OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIG</code>
| SIG2 PK2
+
 
| SIG1 PK1
+
i.e. the message hash used to create the signature excludes the first OP_CHECKSIGVERIFY and the OP_CODESEPARATOR inserted by the script evaluation engine.
| OP_CODESEPARATOR
+
 
| OP_DUP OP_HASH160 <pkh1> OP_EQUALVERIFY OP_CHECKSIG
+
The third OP_CHECKSIG will verify <Sig A> <PK A> on the following message:
| OP_CODESEPARATOR
+
 
| OP_DUP OP_HASH160 <pkh2> OP_EQUALVERIFY OP_CHECKSIG
+
<code>OP_CHECKSIG</code>
|}
+
 
+
i.e. the message hash used to create the signature excludes the first and second instances of OP_CHECKSIGVERIFY and OP_CODESEPARATOR.
In this second example, the OP_CODESEPARATOR which is placed between the two elements of the ScriptPubKey removes the requirement for the keyholder unlocking ScriptPubkey part 2 to sign ScriptPubKey part 1. The keyholder unlocking ScriptPubKey part 1 must sign the entire ScriptPubKey message to unlock the UTXO.
+
 
 +
If someone changes the order of the signature in the ScriptSig, the verification of the signature will fail.

Latest revision as of 00:30, 18 November 2020

OP_CODESEPARATOR was originally designed to be inserted between the ScriptPubKey and ScriptSig by the script evaluation engine. When OP_CHECKSIG is called in the ScriptPubKey, it will remove everything before OP_CODESEPARATOR. In the default case, the entire ScriptSig will be removed as the ScriptSig containing the signature cannot be signed by the signature.

There is no rule to prevent users from inserting OP_CODESEPARATOR into the ScriptPubKey however OP_CODESEPARATOR will only be effective if it is read by OP_CHECKSIG in the same ScriptPubKey. OP_CHECKSIG will read back to the closest OP_CODESEPARATOR before it and remove all message contents before that.

Example

Based on the understanding above, we can construct the following ScriptPubKey:

OP_CODESEPARATOR OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIG

To unlock this ScriptPubKey, we can use the following ScriptSig:

<Sig A> <PK A> <Sig B> <PK B> <Sig C> <PK C>

Note that the first OP_CHECKSIG will verify <Sig C> <PK C> on the following message:

OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIG

The second OP_CHECKSIG will verify <Sig B> <PK B> on the following message:

OP_CHECKSIGVERIFY OP_CODESEPARATOR OP_CHECKSIG

i.e. the message hash used to create the signature excludes the first OP_CHECKSIGVERIFY and the OP_CODESEPARATOR inserted by the script evaluation engine.

The third OP_CHECKSIG will verify <Sig A> <PK A> on the following message:

OP_CHECKSIG

i.e. the message hash used to create the signature excludes the first and second instances of OP_CHECKSIGVERIFY and OP_CODESEPARATOR.

If someone changes the order of the signature in the ScriptSig, the verification of the signature will fail.