<p>A p2sh unlocking script first pushes the actual script, then any stack element needed to fulfill this script. The interpreter will pop one element from the stack and verify if it's hash160 is equal to the one committed in the spk. If yes, then the interpreter destroys the runtime, and build a new one, but using the popped element as script instead.<br />
In your case, bitcoind is interpreting your secret as a script, and it isn't a valid script. Hence, yielding an error about opcodes. The correct way of doing this with p2sh is by taking the hash160 of the hex-encoded script:</p>
<pre><code>OP_HASH160 OP_PUSH20 &lt;your_hash&gt; OP_EQUALVERIFY
</code></pre>
<p>Your program hash is the resulting digest.<br />
When spending, you first push this script, and your secret as a second stack element. Your initial stack looks like this:
<code>&lt;script&gt; &lt;secret&gt;</code></p>

CC BY-SA 4.0
2023-02-06T04:23:46.797Z
I don't follow. Are you saying that my redeem script should have the 0x11 included? So the entire unlocking script would be <11secret key>? Also it's not clear to me why 11<redeem script> wouldn't just push <redeem script> onto the stack, and then the HASH_160 on the unlocking script would pop this off and compare result to script hash. In my case there is no "script" on the unlocking side, I just want to push the redeem script/number on the stack, and be evaluated by the locking script.
Peter
CC BY-SA 4.0
2023-02-06T04:30:27.530Z
Appears I have some confusion with regards to the push byte opcodes. For example this P2SH UTXO https://mempool.space/tx/6f90c7fdcd70a30606ce477d6ebe30280475f48bd668a7db8fef61ef532c7d3a , the redeem script is 00140e90dbfd847487b28ce26055b11826116d040090 and the full unlocking script is 1600140e90dbfd847487b28ce26055b11826116d040090. So 0x16 push 22 bytes onto stack, but then the redeem script also has push 0x14 bytes onto stack (when it is already on stack?)
Peter
CC BY-SA 4.0
2023-02-06T04:33:36.530Z
Following that logic, should my unlocking script be: 12<11secret key>?
Peter
CC BY-SA 4.0
2023-02-06T11:32:25.743Z
What you are missing is that p2sh isn't just the explicit script. If you see the sh template, you make an extra step that is not in the script where the first element is popped out from the stack and used as scrip. Otherwise, you wouldn't run the actual script, just the p2sh template. Take a look at bip 16 to more details. And yes `OP_PUSH18 <script>` where `script` is `<OP_PUSH17 <secret>`. But I think this violates the clean stack rule.
Davidson Souza
CC BY-SA 4.0
2023-02-07T02:35:34.020Z
Alright, I didn't realize P2SH has a different script execution logic, although BIP16 doesn't lay out how this works precisely. Is it correct to say with a P2SH locking script, this somehow triggers a different execution logic, where in the locking script, one must push n bytes of redeem script onto stack, the stack is the copied, the redeem script executed (where 1 must be left on top of stack at end). If 1 on top then stack is replaced by redeem script, where the locking script is executed to compare the hash?
Peter
CC BY-SA 4.0
2023-02-07T02:39:06.810Z
So in my case the unlocking script was never going to work because script was trying to execute my redeem script, which didn't have valid opcodes. However it would work if I had some unlocking script where the redeem script had some logic including the magic number, where it evaluated to true. But ofc changing the redeem script changes the hash, so that locking script can't be unlocked.
Peter
CC BY-SA 4.0
2023-02-07T14:50:56.740Z
About your first comment, the first pass (the one checking if script hash is ok) ends with a clean stack. OP_EQUALVERIFY doesn't push OP_TRUE into the stack, it fails in case of not equal. If the script hash doesn't match, it fails right away. You only run the actual script if this initial check pass. And yes, these funds are lost forever because you need a valid script with the same hash as this one, but this is a collision against hash160.
Davidson Souza
CC BY-SA 4.0
2023-02-07T20:34:09.923Z
So the P2SH execution flow in my example is: 1. Run unlocking script, push 0x11 bytes to stack (ends with redeem script on stack) and stack copied 2. Run locking script, redeem script popped from stack and locking script verifies hash (ending with 1 on stack as OP_EQUAL not OP_EQUALVERIFY) 3. Prior copied stack (contained redeem script) popped off and executed as script. Script fails as magic number contains invalid opcodes. Thanks for your help.
Peter
CC BY-SA 4.0
2023-02-06T02:19:02.467Z
2023-02-06T02:19:02.467Z
Davidson Souza
<p>I am trying to spend a P2SH UTXO based on a redeem script that requires no signatures and simply needs the correct input to equal the OP_HASH160 digest in the corresponding P2SH locking script.</p>
<p>My unlocking script pushes 17 bytes onto the stack (0x11) which are the following 17 bytes that constitute the &quot;secret&quot; number to get the correct hash.</p>
<p>The decoded raw tx is the following (with the 17 byte secret number removed):</p>
<pre><code>&quot;txid&quot;: &quot;0ba564fc00cbeada33ccded7f4e45f17bfff69c8f8a38132dc715de0d905b857&quot;,
&quot;hash&quot;: &quot;0ba564fc00cbeada33ccded7f4e45f17bfff69c8f8a38132dc715de0d905b857&quot;,
&quot;version&quot;: 1,
&quot;size&quot;: 113,
&quot;vsize&quot;: 113,
&quot;weight&quot;: 452,
&quot;locktime&quot;: 0,
&quot;vin&quot;: [
  {
    &quot;txid&quot;: &quot;f8e5dfe32a57872d58cee6f3eb32ec0277f3563306ae623109ea651fd9dc8087&quot;,
    &quot;vout&quot;: 1,
    &quot;scriptSig&quot;: {
      &quot;asm&quot;: &quot;&lt;17 byte redeem script&gt;&quot;,
      &quot;hex&quot;: &quot;11&lt;17 byte redeem script&gt;&quot;
    },
    &quot;sequence&quot;: 4294967295
  }
],
&quot;vout&quot;: [
  {
    &quot;value&quot;: 0.00002000,
    &quot;n&quot;: 0,
    &quot;scriptPubKey&quot;: {
      &quot;asm&quot;: &quot;02de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087c      OP_CHECKSIG&quot;,
      &quot;desc&quot;: &quot;pk(02de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087c)#epafp6sh&quot;,
      &quot;hex&quot;: &quot;2102de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087cac&quot;,
      &quot;type&quot;: &quot;pubkey&quot;
    }
  }
]
}
</code></pre>
<p>I can't see any mistakes however &quot;sendrawtransaction&quot; gives me the error: <code>error code: -26 error message: mandatory-script-verify-flag-failed (Opcode missing or not understood)</code></p>
<p>I had thought maybe this was a non-standard tx and therefore wouldn't be valid unless submitted directly to miner*, however it was my understanding that P2SH allowed the freedom to submit arbitrary redeem scripts, provided the unlocking script is valid and the redeem script equals the redeem script hash in the locking script.</p>
<p>*<code>bitcoin-cli decodescript </code> for my unlocking script hex does give me <code>Type:nonstandard</code></p>

CC BY-SA 4.0
2023-02-06T19:08:07.733Z
Hi Peter, please consider using [regtest, testnet, or signet](https://bitcoin.stackexchange.com/q/17553/5406) instead of mainnet to create experimental transactions.
Murch
<p2sh><p2pk>
P2SH to P2PK transaction - mandatory-script-verify-flag-failed (Opcode missing or not understood) (error 26)
Peter
# P2SH to P2PK transaction - mandatory-script-verify-flag-failed (Opcode missing or not understood) (error 26)

(Asked by: username_0 on 2023-02-06)

I am trying to spend a P2SH UTXO based on a redeem script that requires no signatures and simply needs the correct input to equal the OP\_HASH160 digest in the corresponding P2SH locking script.

My unlocking script pushes 17 bytes onto the stack (0x11) which are the following 17 bytes that constitute the "secret" number to get the correct hash.

The decoded raw tx is the following (with the 17 byte secret number removed):

```
"txid": "0ba564fc00cbeada33ccded7f4e45f17bfff69c8f8a38132dc715de0d905b857",
"hash": "0ba564fc00cbeada33ccded7f4e45f17bfff69c8f8a38132dc715de0d905b857",
"version": 1,
"size": 113,
"vsize": 113,
"weight": 452,
"locktime": 0,
"vin": [
  {
    "txid": "f8e5dfe32a57872d58cee6f3eb32ec0277f3563306ae623109ea651fd9dc8087",
    "vout": 1,
    "scriptSig": {
      "asm": "<17 byte redeem script>",
      "hex": "11<17 byte redeem script>"
    },
    "sequence": 4294967295
  }
],
"vout": [
  {
    "value": 0.00002000,
    "n": 0,
    "scriptPubKey": {
      "asm": "02de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087c      OP_CHECKSIG",
      "desc": "pk(02de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087c)#epafp6sh",
      "hex": "2102de153317307164e7c9918791c7787d9833a3a8201bdff880e631e490cf9a087cac",
      "type": "pubkey"
    }
  }
]
}

```

I can't see any mistakes however "sendrawtransaction" gives me the error: `error code: -26 error message: mandatory-script-verify-flag-failed (Opcode missing or not understood)`

I had thought maybe this was a non-standard tx and therefore wouldn't be valid unless submitted directly to miner\*, however it was my understanding that P2SH allowed the freedom to submit arbitrary redeem scripts, provided the unlocking script is valid and the redeem script equals the redeem script hash in the locking script.

\*`bitcoin-cli decodescript`  for my unlocking script hex does give me `Type:nonstandard`

**Tags:** p2sh, p2pk

> **Comments:**
> **username_1**: Hi username_0, please consider using [regtest, testnet, or signet](https://bitcoin.stackexchange.com/q/17553/5406) instead of mainnet to create experimental transactions.  

---

## 1 answers

### Answer by username_2 on 2023-02-06. Score: 1

A p2sh unlocking script first pushes the actual script, then any stack element needed to fulfill this script. The interpreter will pop one element from the stack and verify if it's hash160 is equal to the one committed in the spk. If yes, then the interpreter destroys the runtime, and build a new one, but using the popped element as script instead.  
In your case, bitcoind is interpreting your secret as a script, and it isn't a valid script. Hence, yielding an error about opcodes. The correct way of doing this with p2sh is by taking the hash160 of the hex-encoded script:

```
OP_HASH160 OP_PUSH20 <your_hash> OP_EQUALVERIFY

```

Your program hash is the resulting digest.  
When spending, you first push this script, and your secret as a second stack element. Your initial stack looks like this:
`<script> <secret>`

> **Comments:**
> **username_0**: I don't follow. Are you saying that my redeem script should have the 0x11 included? So the entire unlocking script would be <11secret key>? Also it's not clear to me why 11<redeem script> wouldn't just push <redeem script> onto the stack, and then the HASH_160 on the unlocking script would pop this off and compare result to script hash. In my case there is no "script" on the unlocking side, I just want to push the redeem script/number on the stack, and be evaluated by the locking script.  
> **username_0**: Appears I have some confusion with regards to the push byte opcodes. For example this P2SH UTXO https://mempool.space/tx/6f90c7fdcd70a30606ce477d6ebe30280475f48bd668a7db8fef61ef532c7d3a , the redeem script is 00140e90dbfd847487b28ce26055b11826116d040090 and the full unlocking script is 1600140e90dbfd847487b28ce26055b11826116d040090. So 0x16 push 22 bytes onto stack, but then the redeem script also has push 0x14 bytes onto stack (when it is already on stack?)  
> **username_0**: Following that logic, should my unlocking script be: 12<11secret key>?  
> **username_2**: What you are missing is that p2sh isn't just the explicit script. If you see the sh template, you make an extra step that is not in the script where the first element is popped out from the stack and used as scrip. Otherwise, you wouldn't run the actual script, just the p2sh template. Take a look at bip 16 to more details. And yes `OP_PUSH18 <script>` where `script` is `<OP_PUSH17 <secret>`. But I think this violates the clean stack rule.  
> **username_0**: Alright, I didn't realize P2SH has a different script execution logic, although BIP16 doesn't lay out how this works precisely. Is it correct to say with a P2SH locking script, this somehow triggers a different execution logic, where in the locking script, one must push n bytes of redeem script onto stack, the stack is the copied, the redeem script executed (where 1 must be left on top of stack at end). If 1 on top then stack is replaced by redeem script, where the locking script is executed to compare the hash?  
> **username_0**: So in my case the unlocking script was never going to work because script was trying to execute my redeem script, which didn't have valid opcodes. However it would work if I had some unlocking script where the redeem script had some logic including the magic number, where it evaluated to true. But ofc changing the redeem script changes the hash, so that locking script can't be unlocked.  
> **username_2**: About your first comment, the first pass (the one checking if script hash is ok) ends with a clean stack. OP_EQUALVERIFY doesn't push OP_TRUE into the stack, it fails in case of not equal. If the script hash doesn't match, it fails right away. You only run the actual script if this initial check pass. And yes, these funds are lost forever because you need a valid script with the same hash as this one, but this is a collision against hash160.  
> **username_0**: So the P2SH execution flow in my example is: 1. Run unlocking script, push 0x11 bytes to stack (ends with redeem script on stack) and stack copied 2. Run locking script, redeem script popped from stack and locking script verifies hash (ending with 1 on stack as OP_EQUAL not OP_EQUALVERIFY) 3. Prior copied stack (contained redeem script) popped off and executed as script. Script fails as magic number contains invalid opcodes. Thanks for your help.  

---

