<ol>
<li><p>For pushing numbers between 1-16, you should be using OP_1-OP_16.</p>
</li>
<li><p>For pushing numbers larger than 16, you should be using OP_PUSH(OP_N/A).</p>
</li>
</ol>
<p>E.g:</p>
<p>&lt;5&gt; push compiles to OP_5: 0x55</p>
<p>&lt;17&gt; push compiles to OP_PUSH1(0x11): 0x0111</p>
<p>&lt;666&gt; push compiles to OP_PUSH2(0x9a02): 0x029a02</p>
<ol start="3">
<li><p>OP_ADD pops two inputs and adds them together. So your ordering is wrong because OP_ADD must come after 3 and 5.</p>
</li>
<li><p>Stack must end with “1” so you should be using OP_NUMEQUAL instead of OP_NUMEQUALVERIFY, which leaves the stack with 1 instead of empty.</p>
</li>
</ol>
<p>Your final script should be:</p>
<pre><code>OP_3 OP_5 OP_ADD OP_EQUAL
</code></pre>
<p>And your unlocking script should be: <code>OP_8</code></p>
<p>You can test it online at: <a href="https://ide.scriptwiz.app/" rel="nofollow noreferrer">https://ide.scriptwiz.app/</a></p>

CC BY-SA 4.0
2021-09-10T17:13:32.603Z
Why note just OP_2 then? That's the unlocking script that adds to 3 to equal 5
Jimbo
CC BY-SA 4.0
2021-09-12T21:33:55.017Z
OP_ADD pops the two previous items which are 3 and 5. Then adds them together, resulting 8 and therefore leaving the stack with 8 8 OP_EQUAL. Finally OP_EQUAL pops the two previous items which are 8 and 8, then compares them.
Burak
CC BY-SA 4.0
2022-08-10T02:50:41.163Z
The script in the question looks like "3 ADD 5 NUMEQUALVERIFY" which would be solved by a witness of "1 2" -- so "ADD" sees "1 2 3" on the stack and replaces the top two leaving "1 5", NUMEQUALVERIFY sees "1 5 5" and removes the top two and doesn't abort since they're equal, and finally just "1" is on the stack which is success.
Anthony Towns
CC BY-SA 4.0
2021-09-10T11:37:56.493Z
2022-08-09T21:01:47.680Z
2022-08-09T21:01:47.680Z
Burak
<blockquote>
<p><strong>I don't understand how the OP_PUSH works - where does it push from and does it push it onto the top of the stack? I thought script operations read from the top of the stack so I'd read the top item and push it back onto the stack which does nothing?</strong></p>
</blockquote>
<p>As I understand it, the script is separate from the stack. The script is read left to right and it's instructions operate on the stack.</p>
<p>So you start with your program pointer at far left of script and with an empty stack.</p>
<p>Then script instructions 0100 (<code>OP_PUSH1 0x00</code>) would push the value <code>0x00</code> from the script onto the top of the stack. The stack would then contain <code>0x00</code> and the program pointer would point to the right of the <code>0x00</code> in the script.</p>
<hr />
<p>As Buruk pointed out, your script is incorrect and wouldn't function as you intend.</p>
<p>I believe you need a locking script</p>
<pre><code>010301059387
</code></pre>
<p>which is</p>
<pre><code>OP_PUSH1 0x03 OP_PUSH1 0x05 OP_ADD OP_EQUAL
</code></pre>
<p>with an unlocking script of</p>
<pre><code>0108
</code></pre>
<p>which is</p>
<pre><code>OP-PUSH1 0x08
</code></pre>
<p>or implicitly</p>
<pre><code> 0108 ...  010301059387


 OP-PUSH1 0x08   ...  OP_PUSH1 0x03 OP_PUSH1 0x05 OP_ADD OP_EQUAL
</code></pre>
<p>which we can work through step by step thus:</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>script</th>
<th>interpretation of highlighted opcode</th>
<th>stack after opcode executed</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>0108</strong>010301059387</td>
<td>OP_PUSH1 0x08</td>
<td>08</td>
</tr>
<tr>
<td>0108<strong>0103</strong>01059387</td>
<td>OP_PUSH1 0x03</td>
<td>03 08</td>
</tr>
<tr>
<td>01080103<strong>0105</strong>9387</td>
<td>OP_PUSH1 0x05</td>
<td>05 03 08</td>
</tr>
<tr>
<td>010801030105<strong>93</strong>87</td>
<td>OP_ADD</td>
<td>08 08</td>
</tr>
<tr>
<td>01080103010593<strong>87</strong></td>
<td>OP_EQUAL</td>
<td>TRUE</td>
</tr>
</tbody>
</table>
</div>
<p>where</p>
<ul>
<li>script is like <a href="https://en.wikipedia.org/wiki/Machine_code" rel="nofollow noreferrer">machine-code</a></li>
<li>interpretation is like <a href="https://en.wikipedia.org/wiki/Assembly_language" rel="nofollow noreferrer">assembly language</a></li>
<li>top of stack is to left</li>
</ul>
<p>It doesn't matter whether you consider opcodes as acting on the top of a stack, bottom of a stack, left of a stack, right of a stack, front of a stack or back of a stack -- so long as all opcodes are <em>consistent in which end they act on</em>. A stack is simply any one-dimensional ordering of items with an arbitrarily chosen direction.
Some languages/libraries might have opcodes/methods/instructions that act on the non-normal end -- you just have to know whether an opcode acts on the normal end or the other end, you could describe those ends as &quot;near&quot; and &quot;far&quot; or any other way you like.</p>
<p>It's just easier to imagine operating on a stack of sheets of paper, on a supporting surface in a gravitational field, where it is physically more convenient to add or remove items from the top than to extract or slide-in items at the bottom. These physical considerations have no meaning in computer operations but we should use words that are consistent with the analogy that is implicit in borrowing the word &quot;stack&quot; from everyday English.</p>
<hr />
<p>Note that</p>
<ul>
<li><code>OP_EQUAL</code> is a bitwise operator that removes two <em>one-byte</em> operands from the stack</li>
<li><code>OP_NUMEQUAL</code> is an arithmetic operator that removes two <em>bigint</em> operands from the stack. Bigints are longer than one byte. I believe each Bigint is 32 bytes (256 bits) on the stack.</li>
<li><code>OP_NUMEQUALVERIFY</code> is <code>OP_NUMEQUAL, OP_VERIFY</code></li>
<li><code>OP_ADD</code> is listed  as an arithmetic operator (not a bitwise operator) which implies it needs two <em>bigint</em> operands on the stack, not two byte values. However it seems to work with byte operands.</li>
</ul>
<p>See <a href="https://siminchen.github.io/bitcoinIDE/build/editor.html" rel="nofollow noreferrer">https://siminchen.github.io/bitcoinIDE/build/editor.html</a></p>

CC BY-SA 4.0
2021-09-10T13:34:04.757Z
2021-09-10T14:33:33.997Z
2021-09-10T14:33:33.997Z
RedGrittyBrick
<p>The locking script I have is</p>
<p>OP_PUSH1(0x03) OP_ADD OP_PUSH1(0x05) OP_NUMEQUALVERIFY</p>
<p>I don't understand how the OP_PUSH works - where does it push from and does it push it onto the top of the stack? I thought script operations read from the top of the stack so I'd read the top item and push it back onto the stack which does nothing?</p>
<p>What would I have to put as an unlocking script on the left to get OP_NUMEQUALVERIFY to return valid here?</p>

<script>
What script unlocks this locking script?
Jimbo
# What script unlocks this locking script?

(Asked by: username_0 on 2021-09-10)

The locking script I have is

OP\_PUSH1(0x03) OP\_ADD OP\_PUSH1(0x05) OP\_NUMEQUALVERIFY

I don't understand how the OP\_PUSH works - where does it push from and does it push it onto the top of the stack? I thought script operations read from the top of the stack so I'd read the top item and push it back onto the stack which does nothing?

What would I have to put as an unlocking script on the left to get OP\_NUMEQUALVERIFY to return valid here?

**Tags:** script


---

## 2 answers

### Answer by username_1 on 2021-09-10. Score: 1 | Accepted answer

1. For pushing numbers between 1-16, you should be using OP\_1-OP\_16.
2. For pushing numbers larger than 16, you should be using OP\_PUSH(OP\_N/A).

E.g:

<5> push compiles to OP\_5: 0x55

<17> push compiles to OP\_PUSH1(0x11): 0x0111

<666> push compiles to OP\_PUSH2(0x9a02): 0x029a02

3. OP\_ADD pops two inputs and adds them together. So your ordering is wrong because OP\_ADD must come after 3 and 5.
4. Stack must end with “1” so you should be using OP\_NUMEQUAL instead of OP\_NUMEQUALVERIFY, which leaves the stack with 1 instead of empty.

Your final script should be:

```
OP_3 OP_5 OP_ADD OP_EQUAL

```

And your unlocking script should be: `OP_8`

You can test it online at: <https://ide.scriptwiz.app/>

> **Comments:**
> **username_0**: Why note just OP_2 then? That's the unlocking script that adds to 3 to equal 5  
> **username_1**: OP_ADD pops the two previous items which are 3 and 5. Then adds them together, resulting 8 and therefore leaving the stack with 8 8 OP_EQUAL. Finally OP_EQUAL pops the two previous items which are 8 and 8, then compares them.  
> **username_2**: The script in the question looks like "3 ADD 5 NUMEQUALVERIFY" which would be solved by a witness of "1 2" -- so "ADD" sees "1 2 3" on the stack and replaces the top two leaving "1 5", NUMEQUALVERIFY sees "1 5 5" and removes the top two and doesn't abort since they're equal, and finally just "1" is on the stack which is success.  

---

### Answer by username_3 on 2021-09-10. Score: 0

> **I don't understand how the OP\_PUSH works - where does it push from and does it push it onto the top of the stack? I thought script operations read from the top of the stack so I'd read the top item and push it back onto the stack which does nothing?**

As I understand it, the script is separate from the stack. The script is read left to right and it's instructions operate on the stack.

So you start with your program pointer at far left of script and with an empty stack.

Then script instructions 0100 (`OP_PUSH1 0x00`) would push the value `0x00` from the script onto the top of the stack. The stack would then contain `0x00` and the program pointer would point to the right of the `0x00` in the script.

---

As Buruk pointed out, your script is incorrect and wouldn't function as you intend.

I believe you need a locking script

```
010301059387

```

which is

```
OP_PUSH1 0x03 OP_PUSH1 0x05 OP_ADD OP_EQUAL

```

with an unlocking script of

```
0108

```

which is

```
OP-PUSH1 0x08

```

or implicitly

```
 0108 ...  010301059387

 OP-PUSH1 0x08   ...  OP_PUSH1 0x03 OP_PUSH1 0x05 OP_ADD OP_EQUAL

```

which we can work through step by step thus:

| script | interpretation of highlighted opcode | stack after opcode executed |
| --- | --- | --- |
| **0108**010301059387 | OP\_PUSH1 0x08 | 08 |
| 0108**0103**01059387 | OP\_PUSH1 0x03 | 03 08 |
| 01080103**0105**9387 | OP\_PUSH1 0x05 | 05 03 08 |
| 010801030105**93**87 | OP\_ADD | 08 08 |
| 01080103010593**87** | OP\_EQUAL | TRUE |

where

* script is like [machine-code](https://en.wikipedia.org/wiki/Machine_code)
* interpretation is like [assembly language](https://en.wikipedia.org/wiki/Assembly_language)
* top of stack is to left

It doesn't matter whether you consider opcodes as acting on the top of a stack, bottom of a stack, left of a stack, right of a stack, front of a stack or back of a stack -- so long as all opcodes are *consistent in which end they act on*. A stack is simply any one-dimensional ordering of items with an arbitrarily chosen direction.
Some languages/libraries might have opcodes/methods/instructions that act on the non-normal end -- you just have to know whether an opcode acts on the normal end or the other end, you could describe those ends as "near" and "far" or any other way you like.

It's just easier to imagine operating on a stack of sheets of paper, on a supporting surface in a gravitational field, where it is physically more convenient to add or remove items from the top than to extract or slide-in items at the bottom. These physical considerations have no meaning in computer operations but we should use words that are consistent with the analogy that is implicit in borrowing the word "stack" from everyday English.

---

Note that

* `OP_EQUAL` is a bitwise operator that removes two *one-byte* operands from the stack
* `OP_NUMEQUAL` is an arithmetic operator that removes two *bigint* operands from the stack. Bigints are longer than one byte. I believe each Bigint is 32 bytes (256 bits) on the stack.
* `OP_NUMEQUALVERIFY` is `OP_NUMEQUAL, OP_VERIFY`
* `OP_ADD` is listed as an arithmetic operator (not a bitwise operator) which implies it needs two *bigint* operands on the stack, not two byte values. However it seems to work with byte operands.

See <https://siminchen.github.io/bitcoinIDE/build/editor.html>


---

