Optimización del almacenamiento para una matriz de direcciones

Cuando es posible, ¿Solidity optimiza una matriz de almacenamiento de address?

Por ejemplo, ¿ address[8]ocupa 5 ranuras de almacenamiento (160 bytes) u 8 ranuras de almacenamiento?

contract C {
  address[8] arr;
}

Si se usan 8 ranuras, ¿hay alguna forma de escribir el código para que Solidity se compile usando solo 5 ranuras? Se aceptan diferentes alternativas, dando preferencia a una forma fácil de acceder a las direcciones (como en arr[2]lugar de jugar con bytes, pero esas respuestas seguirán siendo útiles).

Respuestas (2)

Parece que el almacenamiento no está optimizado. Podemos ver esto usando las herramientas de depuración en la solidez del navegador:

ingrese la descripción de la imagen aquí

Este es un rastro de la setfunción con [1,2,3,4,5,6,7,8]argumentos. Podemos ver que cada dirección usa exactamente una ranura de almacenamiento.

No sé cómo el compilador maneja el almacenamiento en su caso. Pero puede usar la matriz de bytes [160] para almacenar 8 direcciones. Aquí está el código para ello. storeAddress guardará la dirección en la variable direcciones_almacenamiento por índice dado , la función getAddress obtendrá una dirección, previamente almacenada por índice .

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//////////////////////
}

ACTUALIZACIÓN: Lamentablemente, no puedo examinar el código de bytes. Pero basado en la documentación de solidez ( http://solidity.readthedocs.io/en/develop/miscellaneous.html ), donde se dice:

  1. El primer elemento en una ranura de almacenamiento se almacena alineado en orden inferior.
  2. Los tipos elementales usan solo la cantidad de bytes necesarios para almacenarlos.
  3. Si un tipo elemental no cabe en la parte restante de un espacio de almacenamiento, se mueve al siguiente espacio de almacenamiento.
  4. Las estructuras y los datos de matriz siempre comienzan una nueva ranura y ocupan ranuras completas ( pero los elementos dentro de una estructura o matriz se empaquetan estrechamente de acuerdo con estas reglas ).

Y también

  1. Los elementos de structs y arrays se almacenan uno tras otro, como si se dieran explícitamente

Puedo hacer algunas suposiciones: el tipo de dirección es de tipo elemental y su tamaño es de 20 bytes. Entonces, si lo almacena en una matriz de tamaño estático, se convierte en el primer elemento en la nueva ranura (debido a 4) y el espacio libre que queda en esta ranura es de 12 bytes. Es menor que el tamaño de la dirección , es por eso que el siguiente elemento de la dirección debe almacenarse en la siguiente ranura (debido a 3) y así sucesivamente. Entonces, para almacenar N direcciones en una matriz, necesitará N ranuras de memoria. A diferencia del tipo de dirección , los elementos de byte deben llenar densamente las ranuras, y la cantidad de ranuras para almacenar N direcciones debe ser ceil (N * 20/32)

PD En teoría, esto debería funcionar como se explicó anteriormente, pero sería genial si alguien examinara el código de bytes.

Gracias por intentar ayudar. Esperaba que alguien que examine el código de bytes pudiera explicar más sobre las ranuras de almacenamiento de Solidity. Ahora sería interesante ver también cuántas máquinas tragamonedas se byte[160]usan.
@eth respuesta fue actualizada