62

What are the benefits to using string datatypes over bytes32 to represent text data. It seems my contract runs into an out of gas exception when I switch the data structures from bytes32 to string.

4 Answers 4

67

Why string instead of bytes32?

Use string for arbitrary-length string (UTF-8) data that's longer than 32 bytes. Frontends can decode a long string easier using methods like web3.toAscii or UTF-8 (when issues are fixed), instead of implementing the logic of UTF-8 decoding a series of bytes32.

From Solidity docs:

As a rule of thumb, use bytes for arbitrary-length raw byte data and string for arbitrary-length string (UTF-8) data. If you can limit the length to a certain number of bytes, always use one of bytes1 to bytes32 because they are much cheaper.

String literals may also be helpful or convenient:

String literals are written with either double or single-quotes ("foo" or 'bar')...

String literals support escape characters, such as \n, \xNN and \uNNNN. \xNN takes a hex value and inserts the appropriate byte, while \uNNNN takes a Unicode codepoint and inserts an UTF-8 sequence.


Why bytes32 instead of string?

Answered in Why do Solidity examples use bytes32 type instead of string?

bytes32 uses less gas because it fits in a single word of the EVM, and string is a dynamically sized-type which has current limitations in Solidity (such as can't be returned from a function to a contract).

7
  • I am not sure if I understood the last sentence - string return types work in current Solidity compiler. Jan 21, 2017 at 10:10
  • 2
    @MikkoOhtamaa Emphasis is to a contract: I don't think ethereum.stackexchange.com/a/3788/42 is supported yet.
    – eth
    Jan 21, 2017 at 13:53
  • Ok so if you have a controlling contract and it's accessing data from another contract which is returning text that is longer than 32 bytes, you would need to return it in a bytes32 array?
    – ethereal
    Jan 22, 2017 at 17:54
  • @ethereal Sounds right, give a size to the array like bytes32[3]. There may be assembly ways to get the size of the data being returned and avoiding a hardcoded size, for example the contracts in github.com/ownage-ltd/ether-router
    – eth
    Jan 25, 2017 at 0:50
  • 1
    If a contract cannot access another contract's string variables, then what can? Can web3? What if I want to store a list or array of 60-character strings, but I will need to access them from another contract or program, how do I do it?
    – Curt
    Aug 4, 2017 at 1:59
26

Like the other post said, you only want to use strings for dynamically allocated data, otherwise Byte32 is going to perform better. Bytes32 is also going to be better in gas. If you want to play around with it, I built a little fiddle of it https://ethfiddle.com/70ipaEIFdk

Byte used 21465 gas

String used 21897 gas

pragma solidity ^0.4.18;

contract SampleOverflow {
  string constant statictext = "HelloStackOverFlow";
  bytes32 constant byteText = "HelloStackOverFlow";
  function  getString() payable public  returns(string){
    return statictext;
  }

  function  getByte() payable public returns(bytes32){
    return byteText;
  }
}

Get Byte enter image description here

Get String enter image description here https://ethfiddle.com/70ipaEIFdk

1
  • that fiddle doesn't work. I think it's to do with the escaped double quotes. I tried removing escape caharacters but eth fiddle didnt liek that either.. Here's your example working ethfiddle.com/SeXTGt-AWi Dec 30, 2017 at 15:25
2

bytes32 means string with max length 32, It takes less memory than string for the same length of the string.

So, when your data is not more than 32 bytes (32 words), use bytes32.

If the length of the string is not defined, use just bytes.

also, byte8,byte16,byte32 are all available. You can use any as per conditions.

5
  • 1
    Thanks for the simple answer, just want you to clarify the third statement "If the length of the string is not defined, use string." is that case we can use bytes instead of string or bytes32, right? Oct 10, 2022 at 11:00
  • 1
    bytes32 can store up to 32 letters (ASCII), if you require more length, use String.
    – aakash4dev
    Oct 10, 2022 at 11:40
  • 1
    yah i get you but we can use bytes not byte32 to store more length instead of String? Oct 10, 2022 at 12:01
  • 1
    o ya, you are right, sorry, i am updating answer.
    – aakash4dev
    Oct 11, 2022 at 7:19
  • if just leaving at 'bytes', is it set to a certain default #? if so, what is that, is it 'bytes32'? Oct 26, 2022 at 1:41
0

Your system architecture understands that Bytes32 has a maximum of 32 bytes of memory allocation. 1 byte = 1 ASCII character. However, the memory allocation of String data type is not fixed. Hence dynamic.

The design approach will be:

  1. If your intention is to save gas, limit your character range to, 0 to 32 (i.e 32 characters= 32 bytes). Bytes32 is most suitable.
  2. If you are not concerned about gas expense, not sure of the number of characters you are expecting, maybe in your contract function (i.e maybe you are expecting a text as much as Harry Potter novel (lol). String data type is most suitable

Your Answer

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

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