<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](https://github.com/CounterpartyXCP/cips/blob/7303fd60b603b8f38e7da703fb711f0e6c3d6377/cip-0006.md#the-redeem-script) 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).  

---

