5

When possible, does Solidity optimize a storage array of address?

For example, does address[8] take up 5 storage slots (160 bytes), or 8 storage slots?

contract C {
  address[8] arr;
}

If 8 slots are used, is there a way to write the code so that Solidity will compile to only using 5 slots? Different alternatives are welcome, with preference given to an easy way to access the addresses (such as arr[2] instead of twiddling with bytes, but such answers will still be helpful).

1

It appears that the storage is not optimized. We can see this using the debugging tools in browser solidity:

enter image description here

This is a trace of the set function with [1,2,3,4,5,6,7,8] as arguments. We can see that each address uses exactly one storage slot.

0

I do not know how the compiler make deal with storage in your case. But you can use byte[160] array to store 8 addresses. Here is the code for it. storeAddress will save address to addresses_storage variable by given index, function getAddress will get an address, previously stored by index.

pragma solidity ^0.4.0;
contract Addresses5Storage {

    //---------------------BEGIN Code to copy-paste--------------   

    byte[160] private addresses_storage;

    function storeAddress(address addr,uint index)
    {
        uint k=0;
        for (uint i=index*20;i<=(index+1)*20-1;i++)
            addresses_storage[i]=byte((bytes20(addr)<<8*k++)&bytes20(0xff00000000000000000000000000000000000000));    
    }

    function getAddress(uint index) constant
    returns (address)
    {   
        bytes20 addr;
        uint k=0;
        for (uint i=index*20;i<=(index+1)*20-1;i++)
        {
            addr^=bytes20(addresses_storage[i])>>8*k;
            k++;
        }
        return address(addr);
    }

    ////////////////////END Code to copy-paste///////////////////


    //-----------------BEGIN testing stuff code-----------------  
    address[8]  addresses=
        [0x61c2571ac2c83f399a23a1723b3e08ad933267f0,
        0xfa8d3048d236be994a6443fab364c35d2c9934ed,
        0xb6f31f166af597ca40f2f703a4b6b4260124b762,
        0x97b503b07e13e9c104f6091e44bc922f0fd618f6,
        0x3fac7be8070078884feddd5fa2aab30afd7c7ae5,
        0x6fac7be8070078884feddd5fa2aab30afd7c7ae6,
        0x7fac7be8070078884feddd5fa2aab30afd7c7ae7,
        0x8fac7be8070078884feddd5fa2aab30afd7c7ae8];

    //Tests store and get functions. Usage test
    function testStoreAndGet (uint index)
    returns (address)
    {
        storeAddress(addresses[index],index);
        return (getAddress(index));
    }
    //////////////////END testing stuff code//////////////////////
}

UPDATE: Unfortunately I can not examine bytecode. But based on solidity documentation (http://solidity.readthedocs.io/en/develop/miscellaneous.html), where it is said:

  1. The first item in a storage slot is stored lower-order aligned.
  2. Elementary types use only that many bytes that are necessary to store them.
  3. If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot.
  4. Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules).

And also

  1. The elements of structs and arrays are stored after each other, just as if they were given explicitly

I can do some assumptions: type address is elementary type and it size is 20 bytes. So if you store it to staticly sized array it becomes the first element in new slot (because of 4) and free space left in this slot is 12 bytes. It is less then address size, that's why the next address element should be stored in the next slot (because of 3) and so on. So to store N addresses in array you'll need N memory slots. Unlike address type, byte elements should densely fill slots, and the number of slots to store N addresses must be ceil(N*20/32)

P.S. In theory this should work as explained above, but it would be cool if someone examine bytecode.

  • Thanks for trying to help. I was hoping someone who examines bytecode would be able to explain more about Solidity's storage slots. Now it would be interesting to also see how many slots byte[160] uses. – eth Apr 4 '17 at 0:22
  • @eth answer was updated – Alexey Barsuk Apr 4 '17 at 1:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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