<p>In general <code>0 EQUAL</code> is not equivalent to <code>NOT</code>, but in this case they are indeed equivalent.</p>
<p>The reason they're not equivalent in general is that <code>0 EQUAL</code> checks that the top stack element is exactly a canonical 0 push, i.e. the zero-length stack element. <code>NOT</code>, on the other hand, checks that the top stack element is <strong>numerically</strong> equal to 0. This means that it is between 0 and 4 bytes inclusive and all bits are zero except possibly the most significant one, which would indicate -0. If the top stack element has more than 4 bytes then <code>NOT</code> will fail the script immediately, similar to <code>RETURN</code>; there is no way to make <code>0 EQUAL</code> fail the script.</p>
<p>For all these reasons you should be a bit careful using <code>NOT</code> in general -- although in practice standardness rules in most of the network will prevent any of the noncanonical encodings of 0 (or any encoding of -0) to propagate. But in principle if you call <code>NOT</code> directly on witness data then this is a malleability vector.</p>
<p><strong>However</strong>, all of this is moot because the output of <code>DEPTH</code> is guaranteed to be a canonically encoded number. So <code>NOT</code> is perfectly safe and does indeed save the extra byte.</p>

CC BY-SA 4.0
2021-02-18T12:18:09.030Z
`NOT` doesn't seem to fail if input has more than 4 bytes. I tested this by `OP_PUSHDATA1 5 0x0500000000 OP_NOT  OP_1 OP_ADD` [here](https://bitcoin-script-debugger.visvirial.com/) or `500000000 op_not 1 op_add` [here](https://siminchen.github.io/bitcoinIDE/build/editor.html)
MCCCS
CC BY-SA 4.0
2021-02-19T16:55:38.127Z
@MCCCS then those two sites are wrong, and you shouldn't use them as script interpreters. Bitcoin Core interprets the top stack element as a number [here](https://github.com/ElementsProject/elements/blob/master/src/script/interpreter.cpp#L1063) which rejects numbers bigger than 4 [here](https://github.com/ElementsProject/elements/blob/master/src/script/script.h#L238-L240).
Andrew Poelstra
CC BY-SA 4.0
2021-02-14T16:48:25.600Z
2021-02-14T16:48:25.600Z
Andrew Poelstra
<p>I wonder whether</p>
<pre><code>OP_DEPTH 0 OP_EQUAL
</code></pre>
<p>has the exact same behavior as</p>
<pre><code>OP_DEPTH OP_NOT
</code></pre>
<p>which is</p>
<pre><code>1 if no items
0 if any number of items
</code></pre>
<p>I'm asking because the first script is <a href="https://github.com/CounterpartyXCP/cips/blob/7303fd60b603b8f38e7da703fb711f0e6c3d6377/cip-0006.md#the-redeem-script" rel="noreferrer">used</a> and I'm not sure if there is any justification for that. It's very likely that they took the simple approach but I need to make sure about that since I want to squeeze the largest number of bytes out of script.</p>

<script>
Are these two scripts equivalent?
MCCCS
# Are these two scripts equivalent?

(Asked by: username_0 on 2021-02-14)

I wonder whether
OP_DEPTH 0 OP_EQUAL

has the exact same behavior as
OP_DEPTH OP_NOT

which is
1 if no items
0 if any number of items

I'm asking because the first script is used and I'm not sure if there is any justification for that. It's very likely that they took the simple approach but I need to make sure about that since I want to squeeze the largest number of bytes out of script.

**Tags:** script


---

## 1 answers

### Answer by username_1 on 2021-02-14. Score: 7 | Accepted answer

In general `0 EQUAL` is not equivalent to `NOT`, but in this case they are indeed equivalent.

The reason they're not equivalent in general is that `0 EQUAL` checks that the top stack element is exactly a canonical 0 push, i.e. the zero-length stack element. `NOT`, on the other hand, checks that the top stack element is **numerically** equal to 0. This means that it is between 0 and 4 bytes inclusive and all bits are zero except possibly the most significant one, which would indicate -0. If the top stack element has more than 4 bytes then `NOT` will fail the script immediately, similar to `RETURN`; there is no way to make `0 EQUAL` fail the script.

For all these reasons you should be a bit careful using `NOT` in general -- although in practice standardness rules in most of the network will prevent any of the noncanonical encodings of 0 (or any encoding of -0) to propagate. But in principle if you call `NOT` directly on witness data then this is a malleability vector.

**However**, all of this is moot because the output of `DEPTH` is guaranteed to be a canonically encoded number. So `NOT` is perfectly safe and does indeed save the extra byte.

> **Comments:**
> **username_0**: `NOT` doesn't seem to fail if input has more than 4 bytes. I tested this by `OP_PUSHDATA1 5 0x0500000000 OP_NOT  OP_1 OP_ADD` [here](https://bitcoin-script-debugger.visvirial.com/) or `500000000 op_not 1 op_add` [here](https://siminchen.github.io/bitcoinIDE/build/editor.html)  
> **username_1**: @username_0 then those two sites are wrong, and you shouldn't use them as script interpreters. Bitcoin Core interprets the top stack element as a number [here](https://github.com/ElementsProject/elements/blob/master/src/script/interpreter.cpp#L1063) which rejects numbers bigger than 4 [here](https://github.com/ElementsProject/elements/blob/master/src/script/script.h#L238-L240).  

---

