0

I have an smart contract with some defined fixed length variables from 3 to 5 characters long.

Defining these variables as string is more intuitive for those that come from another languages. Also creating unit tests is easier since I have just to pass the plain strings in the calls to the contract functions.

function deposit(string memory _name, uint256 _amount) internal { ... }

await contract.deposit('John', 10);

However, I read that, as I know these are 5-char fixed length variables we can also define them as bytes5 instead of strings. This makes tests more verbose because since you have to make the conversion string->bytes5 and bytes5->string on comparisons.

function deposit(bytes5 _name, uint256 _amount) internal { ... }

let stringToBytes5 = function (str: string) {
    return ethers.utils.hexZeroPad(ethers.utils.toUtf8Bytes(str), 5);
}
let bytes5ToString = function (hexString: string) {
    return ethers.utils.toUtf8String(hexString);
}

await contract.deposit(stringToBytes5('John'), 10);

So I would like to know if using bytes5 is really worth in terms of gas/performance/size... compared to using string.

2 Answers 2

1

According to Solidity docs:

You should use bytes over bytes1[] because it is cheaper, since using bytes1[] in memory adds 31 padding bytes between the elements. Note that in storage, the padding is absent due to tight packing, see bytes and string. As a general rule, 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 the value types bytes1 to bytes32 because they are much cheaper.

Variables of type bytes and string are special arrays. The bytes type is similar to bytes1[], but it is packed tightly in calldata and memory. String is equal to bytes but does not allow length or index access.

So if you can, you should use bytes5 as opposed to string, as long as you are certain such defined fixed length variables won't be longer than 5 characters long.

See: https://docs.soliditylang.org/en/v0.8.12/types.html

1

using bytes is more efficient than using strings, cause they are packed more densely in memory, resulting in less gas usage and a smaller contract size. Cause strings are dynamically-sized, bytes have a fixed size.

But in your case, it may not make a significant difference whether you use a string or bytes5 for a variable that is always 5 characters long. The difference in gas usage and contract size will likely be minimal, and it may be more intuitive for others to read and work with your contract if you use strings instead of bytes.

the decision of whether to use strings or bytes5 in your contract will depend on your specific use case and requirements. You may want to consider benchmarking your contract with both types of variables to see which one performs better in terms of gas usage and contract size.

when deciding whether to use strings or bytes in your contract, you should consider the following:

  • If you need to store dynamically-sized data, such as a user's name or address, you should use strings.
  • If you need to store fixed-size data, such as an ID or hash, you should use bytes with a fixed length. This is more efficient in terms of gas usage and contract size because the data is packed more densely in memory.

an example uses both strings and bytes for different variables:

pragma solidity ^0.5.0;

contract Example {
    // Use a string to store a user's name
    string name;

    // Use bytes32 to store a fixed-size hash
    bytes32 hash;

    // Use address to store an Ethereum address
    address owner;

    function setName(string memory _name) public {
        name = _name;
    }

    function setHash(bytes32 _hash) public {
        hash = _hash;
    }

    function setOwner(address _owner) public {
        owner = _owner;
    }

    function getName() public view returns (string memory) {
        return name;
    }

    function getHash() public view returns (bytes32) {
        return hash;
    }

    function getOwner() public view returns (address) {
        return owner;
    }
}

hope I explain clear.

Your Answer

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

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