33
pragma solidity ^0.4.11;
contract test2 
{

    address creater;
    string username;
    string password;

    function testusernamepassword(string username,string password) returns (bool) 
    {
        if (username == "deepak" && password == "123") //error: operator == is not compatible with string ?
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

7 Answers 7

67

You can compare strings like this:

function compareStrings(string memory a, string memory b) public view returns (bool) {
    return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
}

As a side note: It's not secure at all dealing with passwords and usernames in Solidity.

5
  • 3
    keccak256 is Ethereum's native hash function. ethereum.stackexchange.com/a/554/229
    – ripper234
    Commented Jun 11, 2018 at 12:11
  • 1
    Note, this emits a warning in Remix. imgur.com/a/ruV6IM1
    – ripper234
    Commented Jun 11, 2018 at 12:15
  • Gives following error: equires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding. @pabloruiz55
    – alper
    Commented Mar 7, 2019 at 15:59
  • 1
    @alper That is because of changes in Solidity since 2017. Keccak used to take a tuple of values, now it takes only one. Abi.encodePacked will take a tuple and produce an array of bytes encoding all the elements of that tuple, making it suitable for Keccak.
    – Alex Pinto
    Commented Feb 25, 2020 at 23:24
  • casting to bytes type uses less gas (see Merunas and Joel solution)
    – shamisen
    Commented May 27, 2023 at 8:16
18

Here's the simplest way:

keccak256(bytes(a)) == keccak256(bytes(b));

Just use keccak256() while converting the string to bytes.

2
  • 2
    For checking empty string: keccak256(bytes(a)) == keccak256(bytes("")); will not work. Better: string memory empty = ""; then keccak256(bytes(a)) == keccak256(bytes(empty));
    – Thykof
    Commented Aug 6, 2020 at 9:44
  • Good point you can also compare empty strings with length like so bytes(<your-string>).length == 0 Commented Sep 7, 2022 at 19:40
11

Seems kind of expensive for strings that have a different length, which could be most of the time. What about this solution?

    function memcmp(bytes memory a, bytes memory b) internal pure returns(bool){
        return (a.length == b.length) && (keccak256(a) == keccak256(b));
    }
    function strcmp(string memory a, string memory b) internal pure returns(bool){
        return memcmp(bytes(a), bytes(b));
    }
4

Strings are not really a primitive type in Solidity. There are lots of things that are missing, a bit like in old C. They are a lot like a bytes array, so the low level of comparing would be to treat them as such and iterate over the arrays.

PabloRuiz's answer is a better choice.

If you want to know a little more about strings, you could try my blog post on that subject.

Regarding testing user names and passwords in Solidity, keep in mind that everything you send in a transaction is visible to everyone. The data can be retrieved from a blockchain explorer. The first thing you should try, at least, is to Hash the password, but even then, who ever finds the hash can copy it and relay it for themselves in a fake authentication. In non-blockchain systems, you'd usually use some kind of challenge-response setup. If you could give more details about your authentication setup, people here might be able to give some ideas around it.

0

This is a cleaner version of @pabloruiz55 version. The parenthesis are not necessary and the function can be pure.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract StringComparison {

    function compareStrings(string memory a, string memory b) public pure returns (bool) {
        return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
    }
}

Directly try out the code in Remix here.

0

If you're using Openzeppelin in your project, go ahead and use their function in Strings.sol library:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/6e214227376acd688e60fcdca8cb7f0ae8cef98f/contracts/utils/Strings.sol#L90-L92

0

I actually just built and published a library for dealing with strings in a more traditional way. I have most common js string functions including includes(compareString) and equals(compareString).

To use my library on your local machine:

Install the @tw3/solidity package. (Skip this for Remix IDE users)

npm install @tw3/solidity

Import into your smart contract:

import “@tw3/solidity/contracts/utils/String.sol”

Use it for all string variables:

contract MyContract {
    using String for string;

    function stringsEqual(string memory a, string memory b) public pure returns (bool) {
        return a.equals(b);
    }
}

I’ve currently got the following functions assume string=“strings!”:

  1. string.length() // 8
  2. string.charAt(1) // t
  3. string.startsWith(“str”) // true
  4. string.endsWith(“ing”) // false
  5. string.includes(“z”) // false
  6. string.equals(“strings!”) // true
  7. string.indexOf(“s”) // 0
  8. string.lastIndexOf(“s”) // 6
  9. string.slice(2,-1) // rings
  10. string.split(“i”) // [str,ngs!]
  11. string.toLowerCase() // strings!
  12. strings.toUpperCase() // STRINGS!

Have fun and good luck! Anyone who wants to contribute to my library feel free to find my GitHub repo TechnicallyWeb3/tw3-solidity

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.