Exploring Fixed Byte Size Arrays in Solidity

In this post, we'll explore the concept of fixed byte size arrays in Solidity. These arrays let us work with a set number of bytes, making them very efficient for certain tasks in smart contracts. Let's go through it step by step.


What Are Fixed Byte Size Arrays?

In Solidity, a fixed byte size array uses the bytes data type followed by a number from 1 to 32. This number sets how many bytes the array can hold.

Examples:

bytes1 public b1; // 1-byte array
bytes2 public b2; // 2-byte array

The size is fixed during compilation and cannot be changed later. These arrays are particularly useful for handling binary data with precise size constraints.


Initializing and Viewing Default Values

When a fixed byte size array is declared but not initialized, all its elements default to 0x00.

Code Example:

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract FixedByteArray {
    bytes1 public b1; // Default: 0x00
    bytes2 public b2; // Default: 0x0000
}

Output:

  • b1 = 0x00

  • b2 = 0x0000

Each byte is automatically filled with zeros until explicitly set.


Storing Values in Fixed Byte Size Arrays

Any value stored in a fixed byte size array is automatically converted to its hexadecimal equivalent.

Example:

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract FixedByteArray {
    bytes1 public b1;
    bytes2 public b2;
    bytes3 public b3;

    function setValues() public {
        b1 = "A";       // ASCII of 'A' -> Hex: 0x41
        b2 = "AB";      // 'A' -> 0x41, 'B' -> 0x42
        b3 = "ABC";     // 'A', 'B', 'C' -> 0x41 0x42 0x43
    }
}

Resulting Hex Values:

  • b1 = 0x41

  • b2 = 0x4142

  • b3 = 0x414243

The characters are converted into their hexadecimal ASCII representations and stored.


Padding in Fixed Byte Size Arrays

When a fixed byte size array is only partially initialized, Solidity fills the remaining bytes with 0x00.

Example:

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract FixedByteArray {
    bytes3 public b3;

    function setPartialValue() public {
        b3 = "A"; // Only the first byte is initialized
    }
}

Output:

  • b3 = 0x410000

Explanation:

  • 0x41: Represents "A".

  • 0x00 00: Remaining bytes are padded with zeros.

This behavior ensures that the array always has the full number of bytes specified during declaration.


Immutability of Single Bytes

One limitation of fixed byte size arrays is that individual bytes cannot be modified.

Example:

b3[0] = "C"; // Error: Single bytes cannot be modified directly!

Instead, you must reassign the entire array if you want to update its contents.


Practical Demonstration

Here’s a complete Solidity contract showcasing the functionality of fixed byte size arrays:

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract FixedByteArray {
    bytes1 public b1; // 1-byte array
    bytes2 public b2; // 2-byte array
    bytes3 public b3; // 3-byte array

    // Set values in the arrays
    function setValues() public {
        b1 = "A";      // Hex: 0x41
        b2 = "AB";     // Hex: 0x4142
        b3 = "ABC";    // Hex: 0x414243
    }

    // Demonstrate padding
    function setPartialValue() public {
        b3 = "A"; // Result: 0x410000 (padded with zeros)
    }
}

Steps to Test the Contract:

  1. Deploy the contract.

  2. Check the default values of b1, b2, and b3.

  3. Call the setValues function and verify the updated values in hexadecimal format.

  4. Call the setPartialValue function and observe the padding behavior in b3.


Key Takeaways

  1. Fixed Size: These arrays have a length that is immutable and specified at compile time.

  2. Hexadecimal Storage: Values are stored in hexadecimal format based on their ASCII codes.

  3. Padding: Unused bytes are automatically padded with 0x00.

  4. Immutability: Single bytes cannot be modified individually.

By understanding these concepts, you can use fixed byte size arrays effectively in your Solidity projects.


Conclusion

Fixed byte size arrays offer a compact and efficient method to manage bytes in Solidity. Although their fixed size and immutability might seem restrictive initially, they are very useful in specific situations where you need precise data structures.