How to compare two strings in Solidity

Often in programming, we want to compare two strings. By comparing, I mean we want to identify whether the two strings are equivalent to each other or not.

This is done by using the following operators in other languages:

  • ==: This checks whether two strings are equal

  • !=: This checks if two strings are not equal

In Solidity, there is no native function to compare strings. It is also not possible to compare the equality of two strings by just using the == operator.

Error example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyStrings {
function compare(string memory str1, string memory str2) public pure returns (bool) {
return str1 == str2;
}
}

Executing the above code will throw an error: TypeError: Operator == not compatible with types string memory and string memory

Solidity workaround

So, what is the solution?

Currently, the == operator is only supported for booleans, integers, addresses, and static byte arrays. Solidity does not support == for dynamic arrays, and strings are dynamic arrays.

To work around this, we can simply take the hash of both strings and compare the result.

Example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyStrings {
function compare(string memory str1, string memory str2) public pure returns (bool) {
return keccak256(abi.encodePacked(str1)) == keccak256(abi.encodePacked(str2));
}
}

Explanation

  • keccak256() is a hashing function supported by Solidity

  • abi.encodePacked()encodes a value using the Application Binary Interface (ABI)

Keccak256() is a cryptographic function built into Solidity. This function takes in any amount of inputs and converts it to a unique 32-byte hash. It takes a single bytes parameter as input, so we have to convert our string(s) to bytes first. Therefore, we use the abi.encodePacked() function. It converts input into bytes array.

Gas optimization

The method mentioned above is expensive in terms of gas. However, we can compare the length of the strings first to make it more gas efficient. Then, if the lengths match, we can proceed with the actual comparison.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MyStrings {
function compare(string memory str1, string memory str2) public pure returns (bool) {
if (bytes(str1).length != bytes(str2).length) {
return false;
}
return keccak256(abi.encodePacked(str1)) == keccak256(abi.encodePacked(str2));
}
}

Free Resources