8

I was searching on how to convert a uint to bytes in Solidity and found this answer.

function toBytes(uint256 x) returns (bytes b) {
    b = new bytes(32);
    assembly { mstore(add(b, 32), x) }
}

From the docs mstore(p, v) is mem[p..(p+32)] := v

Which means mstore(add(b, 32), x) translates to mem[(b+32)..(b+64)] := x

What did I understand wrong here? Surely b is 32 bytes and the value of x should be copied inside b not right after it.

Thanks

1 Answer 1

25

The explanation is quite simple:

  1. In Solidity, bytes is a dynamically-sized byte array:

Variables of type bytes and string are special arrays. A bytes is similar to byte[], but it is packed tightly in calldata. string is equal to bytes but does not allow length or index access (for now).

  1. In Solidity Assembly, variables are pointers to memory addresses.

  2. Memory and storage are managed in chunks of 32 bytes.

  3. The first chunk of memory of an Array stores the length of that array.

Now let's look at your code:

b = new bytes(32);

This creates a variable named b of the type bytes.

By 1, we know now the b will be treated as an array.

By 2, we know that b will point to its memory address.

By 3 and 4 we now know that b will point to the length of it, and only 32 bytes after is the memory address where the value for b will start.

We know that add(b, 32) will return the memory address of b added by 32 (in other words, the memory address where to store the value for b).

So, finally we know why mstore(add(b, 32), x) makesb = x.

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.