Skip to content

Strings and Bytes

Strings are actually Arrays, very similar to a bytes-array. If that sounds too complicated, let me break down some quirks for you that are somewhat unique to Solidity:

  1. Natively, there are no String manipulation functions.
  2. No even string comparison is natively possible
  3. There are libraries to work with Strings
  4. Strings are expensive to store and work with in Solidity (Gas costs, we talk about them later)
  5. As a rule of thumb: try to avoid storing Strings, use Events instead (more on that later as well!)

View the Full Course Now

If you still want to use Strings, then let's do an example!

Example Smart Contract

Let's create the following example Smart Contract, store a String and retrieve it again:

//SPDX-License-Identifier: MIT

pragma solidity 0.8.15;

contract ExampleStrings {

    string public myString = "Hello World";

    function setMyString(string memory _myString) public {
        myString = _myString;
    }

}

As shown in the video, run the code. Then update the string to "Hello Earth".

Comparing two Strings

There are no native string comparison functions in Solidity. There is still a way to compare two strings: by comparing their keccak256 hashes.

Extend the contract with the highlighted part:

//SPDX-License-Identifier: MIT

pragma solidity 0.8.15;

contract ExampleStrings {

    string public myString = "Hello World";

    function setMyString(string memory _myString) public {
        myString = _myString;
    }

    function compareTwoStrings(string memory _myString) public view returns(bool) {
        return keccak256(abi.encodePacked(myString)) == keccak256(abi.encodePacked(_myString));
    }

}

Strings vs Bytes

Strings are actually arbitrary long bytes in UTF-8 representation. Strings do not have a length property, bytes do have that. Let's run an example and add a bytes variable with the same "Hello World". Extend the contract with the yellow part:

//SPDX-License-Identifier: MIT

pragma solidity 0.8.15;

contract ExampleStrings {

    string public myString = "Hello World";
    bytes public myBytes = "Hello World";

    function setMyString(string memory _myString) public {
        myString = _myString;
    }

    function compareTwoStrings(string memory _myString) public view returns(bool) {
        return keccak256(abi.encodePacked(myString)) == keccak256(abi.encodePacked(_myString));
    }

    function getBytesLength() public view returns(uint) {
        return myBytes.length;
    }

}

If you run this, you get the length of "Hello World", which is 11. Try to run the same with a non latin-1 character, like an ö.

//SPDX-License-Identifier: MIT

pragma solidity 0.8.15;

contract ExampleStrings {

    string public myString = "Hello World";
    bytes public myBytes = unicode"Hello Wörld";

    function setMyString(string memory _myString) public {
        myString = _myString;
    }

    function compareTwoStrings(string memory _myString) public view returns(bool) {
        return keccak256(abi.encodePacked(myString)) == keccak256(abi.encodePacked(_myString));
    }

    function getBytesLength() public view returns(uint) {
        return myBytes.length;
    }

}

If you run this, you get a length of 12, although its just 11 characters. The character "ö" needs 2 bytes.

Let's now return the myBytes content:

The content is "0x48656c6c6f2057c3b6726c64". If you run it through "web3.utils.toAscii('0x48656c6c6f2057c3b6726c64')" you get back the Ascii representation.

That's about all you need to know about bytes and strings. Let's have a closer look at Ethereum Addresses!