bytes and strings in Solidity

Cryptopusco
3 min readJan 9, 2018

--

In this post we are going to explain why cryptopus smart contracts love bytes & bytes arrays more than strings, which are evil for now.

So, what actually is the difference between bytes and string? Solidity documentation says:

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.

So is there any situation, when string is necessary? The answer is yes, because not all the strings, that are passed as parameters to smart contracts are one-liners.

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.

Dealing with escape characters is always difficult, but Solidity let’s people work with both types of strings.

Never the less would be to mention, that bytes1 to bytes32 use less gas, so they are better for the situations, when there is known for sure, that strings passed to the function are limited to the size of bytes type.

pragma solidity ^0.4.19;

contract BytesOrStrings {
string constant _string = "cryptopus.co Medium";
bytes32 constant _bytes = "cryptopus.co Medium";
function getAsString() public returns(string) {
return _string;
}

function getAsBytes() public returns(bytes32) {
return _bytes;
}
}

Simple smart-contract above is dedicated to demonstrate the difference between both types and Gas Conversion of them. As for bytes32 type, the gas amount used is:

{"transactionHash": "0xa50b4f040acb653735a0d496c34c1b6b5a635e1b21de334fb2427f3e866fbc47","transactionIndex": 0,"blockHash": "0xbfd158d140cec5015baa989dc32f075599ed7186dcc026e86690521ac6b8fb5f","blockNumber": 7,"cumulativeGasUsed": 21484,"gasUsed": 21484,"contractAddress": null}

The string type is not that cheap and comes with:

{"transactionHash": "0x7dc6e89537ff0992a12db432210b5dd7653f9f7bbd16fe56f14c73053134849f","transactionIndex": 0,"blockHash": "0x8cac42f6fddf98cb17e3fcb7c5f94a6db5ca57739407caf68659c12a62ce81a1","blockNumber": 8,"cumulativeGasUsed": 21916,"gasUsed": 21916,"contractAddress": null}

As you can see, the difference between calls is small, but still is. In a bigger examples, where amount of functions and commands is higher that in a sample, it is always important to keep an eye on it.

Second reason to use bytes over string is smart-contract to smart-contract relations. Solidity ver. 0.4.19 is still unable to return string as function’s result for other contracts. It may look like really unnecessary stuff to know, but smart contracts are getting complex with each day and the further it goes, the more contract2contract realtions are going to appear on Blockchain.

Talking about cryptopus API, we use bytes32 as the only format of string storage. Our structures inside Library are all bytes32 oriented:

struct brokerWallet {
bytes32 APIKey;
bytes32 APISecret;
bytes32 historyHash;
bytes32 balanceHash;
uint256 nonce;
}
struct cryptoBroker {
uint8 flag;
bytes32 username;
uint256 registerDate;
}

We also return bytes32 as function results of Storage contract, because this contract is only about to face User Interface contract:

function balanceOf(address _owner, uint256 _position) onlyOLevel external constant returns (bytes32) {
return brokersWallets[_owner][_position].balanceHash;
}
function historyOf(address _owner, uint256 _position) onlyOLevel external constant returns (bytes32) {
return brokersWallets[_owner][_position].balanceHash;
}

In conclusion to this post we want to add, that there is also a workaround for those, who don’t want to use strings in any case. Try to use bytes32[] (arrays). There is an assembly way to get string’s length, so it is possible to allocate as many bytes32 elements as needed.

Thank you for your interest and, please, stay tuned!

We also do love answering questions in our Telegram Chat!

--

--

Cryptopusco

IPFS-based, open-source blockchain tech brokerage marketplace where cryptocurrency investors choose inkognito traders based on their result of the job.