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.
NOT
doesn't seem to fail if input has more than 4 bytes. I tested this byOP_PUSHDATA1 5 0x0500000000 OP_NOT OP_1 OP_ADD
here or500000000 op_not 1 op_add
here – MCCCS Feb 18 '21 at 12:18