<p>I am trying to spend a P2SH multi-signature output which I have created with <a href="https://github.com/rust-bitcoin/rust-bitcoin" rel="nofollow noreferrer">rust-bitcoin</a> as follows:</p>
<pre><code>let builder = Builder::new()
        .push_opcode(opcodes::all::OP_PUSHNUM_2)
        .push_key(&amp;pub_a)
        .push_key(&amp;pub_x)
        .push_opcode(opcodes::all::OP_PUSHNUM_2)
        .push_opcode(OP_CHECKMULTISIG);
Script::new_p2sh(&amp;builder.into_script().script_hash())
</code></pre>
<p>For creating the scriptSig I have the following code:</p>
<pre><code>let sig_a = secp.sign(&amp;msg, &amp;sk.key);
let sig_x = secp.sign(&amp;msg, &amp;x.key);
let sig_a_der = serialize_sig_der_with_sighash(&amp;sig_a, SIGHASH_ALL);
let sig_x_der = serialize_sig_der_with_sighash(&amp;sig_x, SIGHASH_ALL);
let lock_script_bytes: Vec&lt;u8&gt; = lock_script.to_bytes();
// Now we need to combine the original P2SH script and the actual redeem script
let fin_script = Builder::new()
    .push_opcode(opcodes::all::OP_PUSHBYTES_0) /// Needed because of and issue on OP_CHECKMULTISIG
    .push_slice(&amp;sig_x_der)
    .push_slice(&amp;sig_a_der)
    .push_slice(&amp;lock_script_bytes)
    .into_script();

</code></pre>
<p>Now I have tested this on the testnet and am receiving</p>
<p><a href="https://i.sstatic.net/T4UJa.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/T4UJa.png" alt="enter image description here" /></a></p>
<p>I have tried to debug this using <a href="https://github.com/bitcoin-core/btcdeb" rel="nofollow noreferrer">btcdeb</a> and am seeing the following stack before the OP_CHECKMULTISIG executes:</p>
<pre><code>#0015 OP_CHECKMULTISIG
btcdeb&gt; stack
&lt;01&gt;    02      (top)
&lt;02&gt;    02952453888ebcb21720aa81ef9c43ffdb3127b30c5e2d0f61c1c1550b7a29babf
&lt;03&gt;    03dcc4a286cab7209043e5658bfe6ef08adde7128ee5d9bf74862f27ff15f9d519
&lt;04&gt;    02
&lt;05&gt;    3045022100ae1fe1fb0b02586b012ff01be7835269e6079b85f089123ecaf6a482e0324ca602206d2236fd0d07e018097c19e2c9bb8d0b31e18cf51624275b36e596b1969ac3b901
&lt;06&gt;    3045022100bbf92e527688209bacb3e75501fdf1744a7e6e8cd2c922b499d7b40b8dff6260022045845247d1a1fe04aa1ab1866473acf06abc63d5ecdebe6dae0ff7be3200795f01
&lt;07&gt;
btcdeb&gt; step
                &lt;&gt; POP  stack
                &lt;&gt; POP  stack
                &lt;&gt; POP  stack
                &lt;&gt; POP  stack
error: Signature must be zero for failed CHECK(MULTI)SIG operation
btcdeb&gt;
</code></pre>
<p>Afterwards, the stack looks like this:</p>
<pre><code>btcdeb&gt; stack
&lt;01&gt;    3045022100ae1fe1fb0b02586b012ff01be7835269e6079b85f089123ecaf6a482e0324ca602206d2236fd0d07e018097c19e2c9bb8d0b31e18cf51624275b36e596b1969ac3b901                                       (top)
&lt;02&gt;    3045022100bbf92e527688209bacb3e75501fdf1744a7e6e8cd2c922b499d7b40b8dff6260022045845247d1a1fe04aa1ab1866473acf06abc63d5ecdebe6dae0ff7be3200795f01
&lt;03&gt;
</code></pre>
<p>The message for the signature is created as follows:</p>
<pre><code>let sighash = tx.signature_hash(ix, &amp;script_pubkey, SIGHASH_ALL.into());
println!(&quot;msg: {}&quot;, hex::encode(&amp;sighash.as_ref()));
let msg = Message::from_slice(&amp;sighash.as_ref())
    .unwrap();
</code></pre>
<p>which outputs <code>0312f22fd74e55216e51c2724051d8cf9c8833edc1596871fc357a71b3826634</code>.</p>
<p>It seems to me that something is still wrong structurally because after the <code>OP_CHECKMULTISIG</code> has been executed we see that both signatures are actually still on the stack and haven't been popped.</p>

CC BY-SA 4.0
2021-01-25T17:10:11.827Z
Usually problems like this are the result of constructing the message incorrectly. What is the data in `script_pubkey`? It needs to be the multisig script that you are using, not the actual scriptPubKey.
Ava Chow
CC BY-SA 4.0
2021-01-25T17:40:24.287Z
The data in script_pubkey when constructing the signature message is `OP_HASH160 <hash> O_EQUAL` so the scriptPubKey of the input spent. Do I understand correctly that this is incorrect and should actually be the script that is being executed (and wrapped in the P2SH)?
Jakob Nielsen
CC BY-SA 4.0
2021-01-25T17:53:41.560Z
Yes. For P2SH, the script you should be using is the script being executed, i.e. the redeemScript.
Ava Chow
CC BY-SA 4.0
2021-01-25T17:55:19.883Z
@AndrewChow Wow, that fixed it! (well that and I also had the order of the signatures mixed up.) Thanks a lot for your help!
Jakob Nielsen
<script><multi-signature>
OP_CHECKMULTISIG Signature must be zero for failed CHECK(MULTI)SIG operation
Jakob Nielsen
# OP_CHECKMULTISIG Signature must be zero for failed CHECK(MULTI)SIG operation

(Asked by: username_0 on 2021-01-25)

I am trying to spend a P2SH multi-signature output which I have created with rust-bitcoin as follows:
let builder = Builder::new()
        .push_opcode(opcodes::all::OP_PUSHNUM_2)
        .push_key(&pub_a)
        .push_key(&pub_x)
        .push_opcode(opcodes::all::OP_PUSHNUM_2)
        .push_opcode(OP_CHECKMULTISIG);
Script::new_p2sh(&builder.into_script().script_hash())

For creating the scriptSig I have the following code:
let sig_a = secp.sign(&msg, &sk.key);
let sig_x = secp.sign(&msg, &x.key);
let sig_a_der = serialize_sig_der_with_sighash(&sig_a, SIGHASH_ALL);
let sig_x_der = serialize_sig_der_with_sighash(&sig_x, SIGHASH_ALL);
let lock_script_bytes: Vec = lock_script.to_bytes();
// Now we need to combine the original P2SH script and the actual redeem script
let fin_script = Builder::new()
    .push_opcode(opcodes::all::OP_PUSHBYTES_0) /// Needed because of and issue on OP_CHECKMULTISIG
    .push_slice(&sig_x_der)
    .push_slice(&sig_a_der)
    .push_slice(&lock_script_bytes)
    .into_script();


Now I have tested this on the testnet and am receiving

I have tried to debug this using btcdeb and am seeing the following stack before the OP_CHECKMULTISIG executes:
#0015 OP_CHECKMULTISIG
btcdeb> stack
<01>    02      (top)
<02>    02952453888ebcb21720aa81ef9c43ffdb3127b30c5e2d0f61c1c1550b7a29babf
<03>    03dcc4a286cab7209043e5658bfe6ef08adde7128ee5d9bf74862f27ff15f9d519
<04>    02
<05>    3045022100ae1fe1fb0b02586b012ff01be7835269e6079b85f089123ecaf6a482e0324ca602206d2236fd0d07e018097c19e2c9bb8d0b31e18cf51624275b36e596b1969ac3b901
<06>    3045022100bbf92e527688209bacb3e75501fdf1744a7e6e8cd2c922b499d7b40b8dff6260022045845247d1a1fe04aa1ab1866473acf06abc63d5ecdebe6dae0ff7be3200795f01
<07>
btcdeb> step
                <> POP  stack
                <> POP  stack
                <> POP  stack
                <> POP  stack
error: Signature must be zero for failed CHECK(MULTI)SIG operation
btcdeb>

Afterwards, the stack looks like this:
btcdeb> stack
<01>    3045022100ae1fe1fb0b02586b012ff01be7835269e6079b85f089123ecaf6a482e0324ca602206d2236fd0d07e018097c19e2c9bb8d0b31e18cf51624275b36e596b1969ac3b901                                       (top)
<02>    3045022100bbf92e527688209bacb3e75501fdf1744a7e6e8cd2c922b499d7b40b8dff6260022045845247d1a1fe04aa1ab1866473acf06abc63d5ecdebe6dae0ff7be3200795f01
<03>

The message for the signature is created as follows:
let sighash = tx.signature_hash(ix, &script_pubkey, SIGHASH_ALL.into());
println!("msg: {}", hex::encode(&sighash.as_ref()));
let msg = Message::from_slice(&sighash.as_ref())
    .unwrap();

which outputs 0312f22fd74e55216e51c2724051d8cf9c8833edc1596871fc357a71b3826634.
It seems to me that something is still wrong structurally because after the OP_CHECKMULTISIG has been executed we see that both signatures are actually still on the stack and haven't been popped.

**Tags:** script, multi-signature

> **Comments:**
> **username_1**: Usually problems like this are the result of constructing the message incorrectly. What is the data in `script_pubkey`? It needs to be the multisig script that you are using, not the actual scriptPubKey.  
> **username_0**: The data in script_pubkey when constructing the signature message is `OP_HASH160 <hash> O_EQUAL` so the scriptPubKey of the input spent. Do I understand correctly that this is incorrect and should actually be the script that is being executed (and wrapped in the P2SH)?  
> **username_1**: Yes. For P2SH, the script you should be using is the script being executed, i.e. the redeemScript.  
> **username_0**: @AndrewChow Wow, that fixed it! (well that and I also had the order of the signatures mixed up.) Thanks a lot for your help!  

---

## 0 answers

