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:

ethereum-blockchain-developer-image

The content is ā€œ0x48656c6c6f2057c3b6726c64ā€. If you run it through ā€œweb3.utils.toAscii(ā€˜0x48656c6c6f2057c3b6726c64’)ā€ you get back the Ascii representation.

ethereum-blockchain-developer-image

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

Last updated on