<p>The main confusion here comes from this :</p>

<blockquote>
  <p>First, generate the script by concatenating <code>[sigScript][OP_CODESEPARATOR][pubkeyScript]</code></p>
</blockquote>

<p>Then you add :</p>

<blockquote>
  <p>I understand that script execution has evolved from this</p>
</blockquote>

<p>I'm not sure whether you mean "Builds upon this method" or "Has since changed this method", but if it is the former then this might explain the unexpected results that you're getting.  Hopefully my answer can clear this up.</p>

<p>It's true that for a (relatively) short period Bitcoin's script evaluation was done by the way you mentioned, where a <code>CODESEPARATOR</code> was placed between <code>scriptSig</code> and <code>scriptPubkey</code> then the whole thing was concatenated to form a single script which would be executed, but that was changed rather early on in commit <code>6ff5f718b6a67797b2b3bab8905d607ad216ee21</code> which dates to July 31st 2010.</p>

<p>After said change, which introduced a function named <code>VerifyScript</code> in <code>script.cpp</code> (today the logic is in <code>interpreter.cpp</code>), <code>scriptSig</code> and <code>scriptPubkey</code> are no longer concatenated with a <code>CODESEPARATOR</code> between them.  Rather they are executed as <strong>two separate scripts</strong> one after the other, where the stack's contents carries from the first to the second.</p>

<p>The difference is subtle and doesn't really change the flow of <em>standard</em> redemptions, but becomes noticable when a <code>CHECKSIG</code> operation is done within the <code>scriptSig</code>.</p>

<p>Starting from the funding transaction</p>

<pre><code>b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d
</code></pre>

<p>we see that the second output in it is a payment to the following <code>scriptPubKey</code> at index <code>1</code> :</p>

<pre><code>14 2a9bc5447d664c1d0141392a842d23dba45c4f13
NOP2
DROP
</code></pre>

<p><code>OP_CLTV</code> is not active yet, so the opcode <code>0xb1</code> is still <code>NOP2</code>.  </p>

<p>Which is then redeemed by</p>

<pre><code>eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb
</code></pre>

<p>by the input at index <code>1</code> :</p>

<pre><code>0
47
  30
  44
    02
    20 276d6dad3defa37b5f81add3992d510d2f44a317fd85e04f93a1e2daea646602
    02
    20 0f862a0da684249322ceb8ed842fb8c859c0cb94c81e1c5308b4868157a428ee
  01
CODESEPARATOR
1
21 0232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a
1
CHECKMULTISIG
</code></pre>

<p>In the short period before commit <code>6ff5f718</code>, the two scripts would be concated with a <code>CODESEPARATOR</code> placed between them to form the complete script, then execution will start.  We start with an empty stack, and a pointer to the beginning of the script marking the start of what would be the signed <code>scriptCode</code> :</p>

<ol>
<li>Push <code>0</code> onto the stack</li>
<li>Push the signature onto the stack</li>
<li>Execute <code>CODESEPARATOR</code> - mark this point in the script as the start of <code>scriptCode</code> (overwriting the previous value set at the beginning)</li>
<li>Push <code>1</code> onto the stack</li>
<li>Push the pubkey onto the stack</li>
<li>Push <code>1</code> onto the stack</li>
<li>Execute 1-of-1 <code>CHECKMULTISIG</code></li>
</ol>

<p>At this point, we need to construct the <code>scriptCode</code> to be signed.  The rules are :</p>

<ol>
<li>Take the subscript from the last executed <code>CODESEPARATOR</code> up until the end of the script</li>
<li>Remove all <code>CODESEPARATORS</code></li>
<li>Remove all occurences of the signature that is currently being verified</li>
</ol>

<p>Since the signature is actually <em>before</em> the last <code>CODESEPARATOR</code>, rule #3 doesn't come into effect here, but rules #1 and #2 do.  This leaves us with the following <code>scriptCode</code> :</p>

<pre><code>1
21 0232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a
1
CHECKMULTISIG
14 2a9bc5447d664c1d0141392a842d23dba45c4f13
NOP2
DROP
</code></pre>

<p>Which is what you initially came up with, but now let's see how the change at <code>6ff5f718</code> makes a difference.</p>

<p>Recall that we are now dealing with two separate scripts, but none of the other rules change.  The only difference is that these two scripts are executed separately, one after the other, and that the stack that remains from the execution of <code>scriptSig</code> passes on to the execution of <code>scriptPubkey</code>.</p>

<p>We start by executing <code>scriptSig</code> and go through steps #1 - #7 as before, arriving at the same point of <code>CHECKMULTISIG</code> where we construct the <code>scriptCode</code>.
Since the actual executed script now consists of only what was in <code>scriptSig</code>, <code>scriptCode</code> becomes : </p>

<pre><code>1
21 0232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a
1
CHECKMULTISIG
</code></pre>

<p>If this signature check passes (and it does), a value of <code>1</code> is pushed onto the stack, and <code>scriptSig</code> execution ends successfuly.  This stack now passes on to the exectution of <code>scriptPubkey</code> (which is very simple) and eventually left as the final value on the stack, which makes <code>scriptPubkey</code> resolve to <code>True</code>.</p>

<p>This transaction is very interesting really shows how non-trivial commit <code>6ff5f718</code> actually was.  It's a great example.</p>

<p>Another minor thing to note is that this <code>scriptPubKey</code> by itself is an anyone-can-spend script.  This script's conditions are satisfiable simply by passing a single push of an element which evaluates to True (e.g. <code>1</code> - <code>0x51</code>) and that the signature check in <code>scriptSig</code> actually has no significance and does not secure the funds at all.</p>

<p><strong>Edit :</strong></p>

<p>Actually, looking into this some more, it seems that this transaction is specifically mentioned in <a href="https://github.com/bitcoin/bips/blob/master/bip-0017.mediawiki" rel="nofollow noreferrer">BIP-17</a> (which has since been abandoned).  The 20 bytes in <code>scriptPubkey</code> is actually the hash160 of the 1-of-1 multisig script itself :</p>

<pre><code>51210232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a51ae
</code></pre>

<p>This is in fact one of the example bip-17 transactions placed on chain by the bip's author.  Should this bip had been accepted, such a transaction would not be anyone-can-spend.  (you can see more details in the bip itself)</p>

CC BY-SA 4.0
2018-11-23T11:17:46.287Z
2019-01-19T14:36:39.093Z
2019-01-19T14:36:39.093Z
arubi
<p>I figured it out myself (by trying all substrings of the script).</p>

<p>The correct subscript is this:</p>

<p><code>
0000 - 51 21 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c 
0010 - b3 3d 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 
0020 - 14 d5 5a 51 ae END
</code></p>

<p>In other words, it's frame 03 to frame 06:</p>

<p><code>
Frame 03: 1(0x51)
Frame 04: 
0000 - 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c b3 3d 
0010 - 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 14 d5 
0020 - 5a END 
Frame 05: 1(0x51)
Frame 06: OP_CHECKMULTISIG(0xae)
</code></p>

<p>Contrary to normal subscript generation, this subscript does not go to the end of the script (it doesn't include any part of the public key at all).</p>

<p>I am not sure why this is the case.</p>

CC BY-SA 4.0
2018-10-05T14:32:30.633Z
2018-10-05T14:32:30.633Z
Andreas Blaesus
<p>I'm trying to learn the Bitcoin protocol by implementing it, and I've got <code>OP_CHECKSIG</code> working (following instructions in <a href="https://en.bitcoin.it/wiki/OP_CHECKSIG" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/OP_CHECKSIG</a>), but I can't get an transaction input using <code>OP_CHECKMULTISIG</code> to pass signature verification.</p>

<p>Specifically, I'm stuck with the second tx_input of transaction <a href="https://www.blockchain.com/btc/tx/eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb" rel="nofollow noreferrer">eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb</a>, and I suspect that the culprit is subscript (the one to replace signature script in current transaction).</p>

<p>Here's how subscript is computed in my implementation.</p>

<p>First, generate the script by concatenating <code>[sigScript][OP_CODESEPARATOR][pubkeyScript]</code> (I understand that script execution has evolved from this).</p>

<p>So a (parsed) script for the input would be like this:</p>

<p><code>
Frame 00: 0(00)
Frame 01: 
0000 - 30 44 02 20 27 6d 6d ad 3d ef a3 7b 5f 81 ad d3 
0010 - 99 2d 51 0d 2f 44 a3 17 fd 85 e0 4f 93 a1 e2 da 
0020 - ea 64 66 02 02 20 0f 86 2a 0d a6 84 24 93 22 ce 
0030 - b8 ed 84 2f b8 c8 59 c0 cb 94 c8 1e 1c 53 08 b4 
0040 - 86 81 57 a4 28 ee 01 END 
Frame 02: OP_CODESEPARATOR(0xab)
Frame 03: 1(0x51)
Frame 04: 
0000 - 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c b3 3d 
0010 - 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 14 d5 
0020 - 5a END 
Frame 05: 1(0x51)
Frame 06: OP_CHECKMULTISIG(0xae)
Frame 07: OP_CODESEPARATOR(0xab)
Frame 08: 
0000 - 2a 9b c5 44 7d 66 4c 1d 01 41 39 2a 84 2d 23 db 
0010 - a4 5c 4f 13 END 
Frame 09: OP_NOP2/OP_CHECKLOCKTIMEVERIFY(0xb1)
Frame 10: OP_DROP(0x75)
</code></p>

<p>Then, I create the subscript from the closest <code>OP_CODESEPARATOR</code> before the <code>OP_CHECKMULTISIG</code> that I am executing till the end of the script. So, I include Frame 03 to Frame 10.</p>

<p>Then, I remove other <code>OP_CODESEPARATOR</code>s in the script, which is Frame 07.</p>

<p>That means these frames should compose the subscript:</p>

<p><code>
Frame 03: 1(0x51)
Frame 04: 
0000 - 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c b3 3d 
0010 - 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 14 d5 
0020 - 5a END 
Frame 05: 1(0x51)
Frame 06: OP_CHECKMULTISIG(0xae)
Frame 08: 
0000 - 2a 9b c5 44 7d 66 4c 1d 01 41 39 2a 84 2d 23 db 
0010 - a4 5c 4f 13 END 
Frame 09: OP_NOP2/OP_CHECKLOCKTIMEVERIFY(0xb1)
Frame 10: OP_DROP(0x75)
</code></p>

<p>Serialized, the final subscript looks like this:</p>

<p><code>
0000 - 51 21 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c 
0010 - b3 3d 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 
0020 - 14 d5 5a 51 ae 14 2a 9b c5 44 7d 66 4c 1d 01 41 
0030 - 39 2a 84 2d 23 db a4 5c 4f 13 b1 75
</code></p>

<p>However, when this subscript is used to replace signature script, and eventually generate hash, the ecdsa_verify function reports that signature verification fails (but the inputs are legal).</p>

<p>Since the same procedure works for <code>OP_CHECKSIG</code>, I probably missed something obvious, but I couldn't figure this out reading the original Satoshi code, the current implementation, or Bitcoin Wiki.</p>

<p>If it helps, my code for OP_CHECKMULTISIG is here:
<a href="https://github.com/blaesus/tinybtc/blob/checkmultisig/src/script.c#L687" rel="nofollow noreferrer">https://github.com/blaesus/tinybtc/blob/checkmultisig/src/script.c#L687</a></p>

<p>A more simplistic version (using prevTx.pubkeyScript as subscript) doesn't yield valid results either: <a href="https://github.com/blaesus/tinybtc/blob/validate/src/script.c#L344" rel="nofollow noreferrer">https://github.com/blaesus/tinybtc/blob/validate/src/script.c#L344</a></p>

CC BY-SA 4.0
2019-02-18T15:14:16.507Z
What are the frames you're talking about?
Pieter Wuille
<script><protocol><multi-signature><checksig>
How is subscript computed for OP_CHECKMULTISIG?
Andreas Blaesus
# How is subscript computed for OP_CHECKMULTISIG?

(Asked by: username_0 on 2018-10-04)

I'm trying to learn the Bitcoin protocol by implementing it, and I've got `OP_CHECKSIG` working (following instructions in <https://en.bitcoin.it/wiki/OP_CHECKSIG>), but I can't get an transaction input using `OP_CHECKMULTISIG` to pass signature verification.

Specifically, I'm stuck with the second tx\_input of transaction [eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb](https://www.blockchain.com/btc/tx/eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb), and I suspect that the culprit is subscript (the one to replace signature script in current transaction).

Here's how subscript is computed in my implementation.

First, generate the script by concatenating `[sigScript][OP_CODESEPARATOR][pubkeyScript]` (I understand that script execution has evolved from this).

So a (parsed) script for the input would be like this:

`Frame 00: 0(00)
Frame 01:
0000 - 30 44 02 20 27 6d 6d ad 3d ef a3 7b 5f 81 ad d3
0010 - 99 2d 51 0d 2f 44 a3 17 fd 85 e0 4f 93 a1 e2 da
0020 - ea 64 66 02 02 20 0f 86 2a 0d a6 84 24 93 22 ce
0030 - b8 ed 84 2f b8 c8 59 c0 cb 94 c8 1e 1c 53 08 b4
0040 - 86 81 57 a4 28 ee 01 END
Frame 02: OP_CODESEPARATOR(0xab)
Frame 03: 1(0x51)
Frame 04:
0000 - 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c b3 3d
0010 - 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 14 d5
0020 - 5a END
Frame 05: 1(0x51)
Frame 06: OP_CHECKMULTISIG(0xae)
Frame 07: OP_CODESEPARATOR(0xab)
Frame 08:
0000 - 2a 9b c5 44 7d 66 4c 1d 01 41 39 2a 84 2d 23 db
0010 - a4 5c 4f 13 END
Frame 09: OP_NOP2/OP_CHECKLOCKTIMEVERIFY(0xb1)
Frame 10: OP_DROP(0x75)`

Then, I create the subscript from the closest `OP_CODESEPARATOR` before the `OP_CHECKMULTISIG` that I am executing till the end of the script. So, I include Frame 03 to Frame 10.

Then, I remove other `OP_CODESEPARATOR`s in the script, which is Frame 07.

That means these frames should compose the subscript:

`Frame 03: 1(0x51)
Frame 04:
0000 - 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c b3 3d
0010 - 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 14 d5
0020 - 5a END
Frame 05: 1(0x51)
Frame 06: OP_CHECKMULTISIG(0xae)
Frame 08:
0000 - 2a 9b c5 44 7d 66 4c 1d 01 41 39 2a 84 2d 23 db
0010 - a4 5c 4f 13 END
Frame 09: OP_NOP2/OP_CHECKLOCKTIMEVERIFY(0xb1)
Frame 10: OP_DROP(0x75)`

Serialized, the final subscript looks like this:

`0000 - 51 21 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c
0010 - b3 3d 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4
0020 - 14 d5 5a 51 ae 14 2a 9b c5 44 7d 66 4c 1d 01 41
0030 - 39 2a 84 2d 23 db a4 5c 4f 13 b1 75`

However, when this subscript is used to replace signature script, and eventually generate hash, the ecdsa\_verify function reports that signature verification fails (but the inputs are legal).

Since the same procedure works for `OP_CHECKSIG`, I probably missed something obvious, but I couldn't figure this out reading the original Satoshi code, the current implementation, or Bitcoin Wiki.

If it helps, my code for OP\_CHECKMULTISIG is here:
<https://github.com/blaesus/tinybtc/blob/checkmultisig/src/script.c#L687>

A more simplistic version (using prevTx.pubkeyScript as subscript) doesn't yield valid results either: <https://github.com/blaesus/tinybtc/blob/validate/src/script.c#L344>

**Tags:** script, protocol, multi-signature, checksig

> **Comments:**
> **username_1**: What are the frames you're talking about?  

---

## 2 answers

### Answer by username_2 on 2018-11-23. Score: 2 | Accepted answer

The main confusion here comes from this :

First, generate the script by concatenating [sigScript][OP_CODESEPARATOR][pubkeyScript]

Then you add :

I understand that script execution has evolved from this

I'm not sure whether you mean "Builds upon this method" or "Has since changed this method", but if it is the former then this might explain the unexpected results that you're getting.  Hopefully my answer can clear this up.
It's true that for a (relatively) short period Bitcoin's script evaluation was done by the way you mentioned, where a CODESEPARATOR was placed between scriptSig and scriptPubkey then the whole thing was concatenated to form a single script which would be executed, but that was changed rather early on in commit 6ff5f718b6a67797b2b3bab8905d607ad216ee21 which dates to July 31st 2010.
After said change, which introduced a function named VerifyScript in script.cpp (today the logic is in interpreter.cpp), scriptSig and scriptPubkey are no longer concatenated with a CODESEPARATOR between them.  Rather they are executed as two separate scripts one after the other, where the stack's contents carries from the first to the second.
The difference is subtle and doesn't really change the flow of standard redemptions, but becomes noticable when a CHECKSIG operation is done within the scriptSig.
Starting from the funding transaction
b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d

we see that the second output in it is a payment to the following scriptPubKey at index 1 :
14 2a9bc5447d664c1d0141392a842d23dba45c4f13
NOP2
DROP

OP_CLTV is not active yet, so the opcode 0xb1 is still NOP2.  
Which is then redeemed by
eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb

by the input at index 1 :
0
47
  30
  44
    02
    20 276d6dad3defa37b5f81add3992d510d2f44a317fd85e04f93a1e2daea646602
    02
    20 0f862a0da684249322ceb8ed842fb8c859c0cb94c81e1c5308b4868157a428ee
  01
CODESEPARATOR
1
21 0232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a
1
CHECKMULTISIG

In the short period before commit 6ff5f718, the two scripts would be concated with a CODESEPARATOR placed between them to form the complete script, then execution will start.  We start with an empty stack, and a pointer to the beginning of the script marking the start of what would be the signed scriptCode :

Push 0 onto the stack
Push the signature onto the stack
Execute CODESEPARATOR - mark this point in the script as the start of scriptCode (overwriting the previous value set at the beginning)
Push 1 onto the stack
Push the pubkey onto the stack
Push 1 onto the stack
Execute 1-of-1 CHECKMULTISIG

At this point, we need to construct the scriptCode to be signed.  The rules are :

Take the subscript from the last executed CODESEPARATOR up until the end of the script
Remove all CODESEPARATORS
Remove all occurences of the signature that is currently being verified

Since the signature is actually before the last CODESEPARATOR, rule #3 doesn't come into effect here, but rules #1 and #2 do.  This leaves us with the following scriptCode :
1
21 0232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a
1
CHECKMULTISIG
14 2a9bc5447d664c1d0141392a842d23dba45c4f13
NOP2
DROP

Which is what you initially came up with, but now let's see how the change at 6ff5f718 makes a difference.
Recall that we are now dealing with two separate scripts, but none of the other rules change.  The only difference is that these two scripts are executed separately, one after the other, and that the stack that remains from the execution of scriptSig passes on to the execution of scriptPubkey.
We start by executing scriptSig and go through steps #1 - #7 as before, arriving at the same point of CHECKMULTISIG where we construct the scriptCode.
Since the actual executed script now consists of only what was in scriptSig, scriptCode becomes : 
1
21 0232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a
1
CHECKMULTISIG

If this signature check passes (and it does), a value of 1 is pushed onto the stack, and scriptSig execution ends successfuly.  This stack now passes on to the exectution of scriptPubkey (which is very simple) and eventually left as the final value on the stack, which makes scriptPubkey resolve to True.
This transaction is very interesting really shows how non-trivial commit 6ff5f718 actually was.  It's a great example.
Another minor thing to note is that this scriptPubKey by itself is an anyone-can-spend script.  This script's conditions are satisfiable simply by passing a single push of an element which evaluates to True (e.g. 1 - 0x51) and that the signature check in scriptSig actually has no significance and does not secure the funds at all.
Edit :
Actually, looking into this some more, it seems that this transaction is specifically mentioned in BIP-17 (which has since been abandoned).  The 20 bytes in scriptPubkey is actually the hash160 of the 1-of-1 multisig script itself :
51210232abdc893e7f0631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a51ae

This is in fact one of the example bip-17 transactions placed on chain by the bip's author.  Should this bip had been accepted, such a transaction would not be anyone-can-spend.  (you can see more details in the bip itself)


---

### Answer by username_0 on 2018-10-05. Score: 0

I figured it out myself (by trying all substrings of the script).

The correct subscript is this:

`0000 - 51 21 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c
0010 - b3 3d 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4
0020 - 14 d5 5a 51 ae END`

In other words, it's frame 03 to frame 06:

`Frame 03: 1(0x51)
Frame 04:
0000 - 02 32 ab dc 89 3e 7f 06 31 36 4d 7f d0 1c b3 3d
0010 - 24 da 45 32 9a 00 35 7b 3a 78 86 21 1a b4 14 d5
0020 - 5a END
Frame 05: 1(0x51)
Frame 06: OP_CHECKMULTISIG(0xae)`

Contrary to normal subscript generation, this subscript does not go to the end of the script (it doesn't include any part of the public key at all).

I am not sure why this is the case.


---

