37

Can someone help out with the stated error, I am trying to run code to check the status of a String variable. While compiling using the online solidity compiler I am getting two errors on customcheck and portcheck. See the code below:

contract tradefin {

    uint public prodcode;
    address public seller;
    address public buyer;
    uint public price;
    uint public units;
    address public port;
    address public customs;
    address public delivery;
    string public portcheck;
    string public customscheck;
    string public deliverycheck;
    string public msg1;


    function initiate(uint code, address vendor, address applicant, 
        uint amount, uint quantity, address p, address c, address d) {
        prodcode = code;
        seller = vendor;
        buyer = applicant;
        price = amount;
        units = quantity;
        port = p;
        customs = c;
        delivery = d;
    }

    function review() constant returns (uint retval) {
        return uint(prodcode);
    }

    function finall() constant returns (string retval) {
        return string(deliverycheck);
    }    

    function approve() constant returns (string retval) {
        if (msg.sender == port) {
            portcheck = "signed";
        }

        if (msg.sender == customs) {
            if (portcheck == "signed")             
                customscheck = "signed";
            else 
                msg1 = "Port yet to sign";
            return msg1;
        }
    
        if (msg.sender == delivery) {
            if (customscheck == "signed")
                deliverycheck = "signed";
            else            
                msg1 = "Custom yet to sign";
            return msg1;            
        }
    }    
}

4 Answers 4

16

As in Java, the == operator does not compare the literals of two strings. You should use the StringUtils contract instead.

if (StringUtils.equal(portcheck,"signed")) {...}
2
  • 1
    thanks Roland that helped. i ended up trying something else (used address to validate), can you help with another question around the same code (changed a bit), you can view it at 4631 -> in your search bar.
    – srbamb
    Jun 3, 2016 at 17:03
  • Too old answer. Even library itself seems to be deprecated. Aug 31, 2022 at 6:23
66

If you don't want to load the StringUtils contract, I found it's also possible to simply: keccak256(portcheck) == keccak256("signed").

Can anyone confirm that this would also cost less gas than a function which evaluates each char of both strings?

(Sorry if adding an answer to a Q with a "checked" response is frowned upon... I just noticed that this method hadn't been mentioned and thought it might be helpful!)

EDIT: Just created a quick gas mileage harness and it looks like my suspicions were right. keccak256 comparison uses dramatically less gas than character comparison.

EDIT: Originally called sha3, but the use of this function has now been deprecated in favour of keccak256 (sha3 is an alias to keccak256)

3
  • 3
    wow would of never thought of this. simple and it works. May 26, 2017 at 1:12
  • 1
    You can also pre-compute keccak256("signed") and hardcode the value into the contract for further gas savings, right? Apr 15, 2019 at 11:58
  • 14
    keccak256(bytes(portcheck)) == keccak256(bytes("signed"))
    – moeabdol
    Jul 21, 2019 at 13:10
3

When possible, strings should not be used to describe state.

For example, the state of a switch can be modeled with trueand false.

For cases where more possibilities exist, solidity has enums. As they are just unsigned integers under the hood, they are much easier (and cheaper) to work with.

Of course there are cases like Oraclize queries where StringUtils is necessary.

2

I wrote small function to compare two strings. First, it converts strings to bytes arrays, then compares lengths of these arrays. After that it compares bytes at the arrays.

So equal strings should have same length and same bytes at same index, otherwise it strings not equal.

function stringsEquals(string memory s1, string memory s2) private pure returns (bool) {
    bytes memory b1 = bytes(s1);
    bytes memory b2 = bytes(s2);
    uint256 l1 = b1.length;
    if (l1 != b2.length) return false;
    for (uint256 i=0; i<l1; i++) {
        if (b1[i] != b2[i]) return false;
    }
    return true;
}
1
  • Your answer can be improved. Explain more about your code snippet, don't write code without explanation.
    – egjlmn1
    Nov 21, 2021 at 7:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.