Speicheroptimierung für ein Array von Adressen

Optimiert Solidity nach Möglichkeit ein Speicher-Array von address?

Nimmt beispielsweise address[8]5 Speicherplätze (160 Byte) oder 8 Speicherplätze in Anspruch?

contract C {
  address[8] arr;
}

Wenn 8 Slots verwendet werden, gibt es eine Möglichkeit, den Code so zu schreiben, dass Solidity so kompiliert wird, dass nur 5 Slots verwendet werden? Verschiedene Alternativen sind willkommen, wobei ein einfacher Weg zum Zugriff auf die Adressen bevorzugt wird (z. B. arr[2]anstatt mit Bytes herumzuspielen, aber solche Antworten sind immer noch hilfreich).

Antworten (2)

Der Speicher scheint nicht optimiert zu sein. Wir können dies mit den Debugging-Tools in Browser Solidity sehen:

Geben Sie hier die Bildbeschreibung ein

Dies ist eine Ablaufverfolgung der setFunktion mit [1,2,3,4,5,6,7,8]als Argumenten. Wir können sehen, dass jede Adresse genau einen Speicherplatz verwendet.

Ich weiß nicht, wie der Compiler in Ihrem Fall mit der Speicherung umgeht. Aber Sie können das Array byte[160] verwenden, um 8 Adressen zu speichern. Hier ist der Code dafür. storeAddress speichert die Adresse nach dem gegebenen Index in der Variable address_storage , die Funktion getAddress ruft eine Adresse ab, die zuvor durch den Index gespeichert wurde .

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: Bytecode kann ich leider nicht untersuchen. Aber basierend auf Solidity-Dokumentation ( http://solidity.readthedocs.io/en/develop/miscellaneous.html ), wo es heißt:

  1. Der erste Gegenstand in einem Lagerplatz wird nachrangig ausgerichtet abgelegt.
  2. Elementare Typen verwenden nur so viele Bytes, wie notwendig sind, um sie zu speichern.
  3. Wenn ein elementarer Typ nicht in den verbleibenden Teil eines Lagerplatzes passt, wird er in den nächsten Lagerplatz verschoben.
  4. Strukturen und Array-Daten beginnen immer einen neuen Slot und belegen ganze Slots ( aber Elemente innerhalb einer Struktur oder eines Arrays werden gemäß diesen Regeln dicht gepackt ).

Und auch

  1. Die Elemente von Structs und Arrays werden nacheinander gespeichert, so als ob sie explizit angegeben wären

Ich kann einige Annahmen treffen: Typadresse ist elementarer Typ und hat eine Größe von 20 Bytes. Wenn Sie es also in einem Array mit statischer Größe speichern, wird es das erste Element in einem neuen Steckplatz (wegen 4), und der in diesem Steckplatz verbleibende freie Speicherplatz beträgt 12 Bytes. Es ist kleiner als die Adressgröße , deshalb sollte das nächste Adresselement im nächsten Slot gespeichert werden (wegen 3) und so weiter. Um also N Adressen in einem Array zu speichern, benötigen Sie N Speicherplätze. Im Gegensatz zum Adresstyp sollten Byte - Elemente Slots dicht füllen, und die Anzahl der Slots zum Speichern von N Adressen muss ceil(N*20/32) sein.

PS Theoretisch sollte das wie oben erklärt funktionieren, aber es wäre cool, wenn jemand den Bytecode untersuchen würde.

Danke für den Versuch zu helfen. Ich hatte gehofft, jemand, der Bytecode untersucht, könnte mehr über die Speicherplätze von Solidity erklären. Nun wäre es interessant zu sehen, wie viele Slots byte[160]verwendet werden.
@eth Antwort wurde aktualisiert