cashscript icon indicating copy to clipboard operation
cashscript copied to clipboard

type consistency with boolean comparisons

Open A60AB5450353F40E opened this issue 1 year ago • 4 comments

bool b, bool a;

a == b should compile to OP_NUMEQUAL (rather than OP_EQUAL) a != b should compile to OP_NUMNOTEQUAL (rather than OP_EQUAL OP_NOT)

A60AB5450353F40E avatar Sep 18 '24 10:09 A60AB5450353F40E

thanks for opening this issue!

In the first case I don't see why it would matter to use OP_NUMEQUAL rather than OP_EQUAL (they are functionally the same in this case so what is the benefit of making the breaking change?)

the second case would indeed save one opcode 👍 I quickly confirmed the compiler behavior on the playground

Making breaking changes to the compiler is only something we want to do very infrequently

mr-zwets avatar Sep 22 '24 09:09 mr-zwets

I stand corrected that both are functionally the same

OP_NUMEQUAL matters for cases like positive and negative zero, which are equal numerically but not when doing OP_EQUAL I think the only way to get to negative zero is to use int(0x80) which could happen I guess

mr-zwets avatar May 08 '25 06:05 mr-zwets

require(bool(int(0x80)) == false);

compiles to OP_0 OP_EQUALVERIFY which would return false

so

int negativeZero = int(0x80);
bool falsyBool = bool(negativeZero);
require(falsyBool == false); // this will fail because of OP_EQUALVERIFY instead of OP_NUMEQUAL 

edit: this can also be done with bool's directly

contract Example() {
    function transfer(bool test) {
        if(test == false){
            require(tx.outputs.length == 2);
        } else {
            require(tx.outputs.length == 1); // negative zero would end up in this case
        }
    }
}

mr-zwets avatar May 08 '25 06:05 mr-zwets

Let's get back to this after we've resolved type casting quirks.

rkalis avatar May 08 '25 11:05 rkalis