1

From solidity docs, in section Layout of State Variables in Storage > bytes and strings

There is this explanation (v: v0.8.21):

In particular: if the data is at most 31 bytes long, the elements are stored in the higher-order bytes (left aligned) and the lowest-order byte stores the value length * 2. For byte arrays that store data which is 32 or more bytes long, the main slot p stores length * 2 + 1 and the data is stored as usual in keccak256(p). This means that you can distinguish a short array from a long array by checking if the lowest bit is set: short (not set) and long (set).

The way I understand it, in both cases, short or long there would be something at the lowest order bit location.

In short string case, last bytes would have length * 2.

For example, string hello would look like 0x68656c6c6f00000000000000000000000000000000000000000000000000000a and hello there would look like 0x68656c6c6f207468657265000000000000000000000000000000000000000016. These are both under 32 characters and have their length times 2 in lowest significant bits as expected.

In long string case, least order bits (and the only item in that storage location) would have length * 2 + 1.

For example, hello therehello therehello therehello therehello therehello therehello there would look like 0x000000000000000000000000000000000000000000000000000000000000009b Again, the lowest order bits would contain the length information, this time length * 2 + 1.

My confusion is with the last sentence from above docs:

This means that you can distinguish a short array from a long array by checking if the lowest bit is set: short (not set) and long (set).

Is this a remnant from an older version of solidity where short strings did not have their length information as part of the storage slot? By just looking at the least significant bits (as that sentence implies), how can we tell if something is a short version string or a long version string? Am I missing something here or do docs just need to be updated here?

1 Answer 1

1

If the low bytes have a value of less than 32, then the string is short, and the text is located in the higher order bytes.

This is likely done to save space, similar to packing variables less than 32 bytes long.

3
  • True and good observation there but it still does not explain the wording in docs. Specifically, the last sentence. Lowest bit IS still set, regardless of if it's a short or long string.
    – SKA
    Oct 24, 2023 at 12:22
  • 1
    That's right - that's the bit Any string length multiplied by two gives a number where the least significant bit == 0. So for a long string, the formula: length * 2 + 1 will always set the low-order bit == 1. You can check the bit in different ways. For example value % 2 == 1 ? or value & 1 == 1 ? Oct 25, 2023 at 6:30
  • Ahhh right, thank you Alexey! I knew there was something simple I was missing there.
    – SKA
    Oct 25, 2023 at 11:21

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.