Arrays

將數據追加到儲存陣列中

  • August 4, 2022

如何將數據附加到儲存陣列中?

例如,假設我們從一個看起來像這樣的數組開始:

[0]

並希望以如下所示的數組結尾:

[0,1]

要儲存動態數組,您首先必須獲得一個起始儲存槽。

假設我們的起始儲存槽是 n。

然後要獲取第一個值的儲存槽,您只需像這樣散列 n :

keccak256(n);

這將為您提供保存第一個變數的儲存槽。

然後,如果您想將某些內容推送到數組中,請再次計算雜湊並添加 1:

keccak256(n) + 1;

等等。

因此,它看起來像這樣:

#define macro STORE_BYTES32() = takes(0) returns(0) {
   0x04 calldataload    // [Argument to store]
   [STARTING_SLOT]      // [StartingSLot, Argument]
   0x00 mstore          // [Argument]
   0x20 0x00            // [offset, size, Argument]
   sha3                 // [HashedStorageSlot, Argument]
   sstore               // []
}

這儲存了第一個值。要在 sha3 之後儲存第二個值,只需向其添加 1。

此外,在solidity 中,第一個儲存槽n 保存數組的大小。

這就是 EVM 知道將下一個變數推送到哪裡的方式。

我創建了一個顯示如何做動態數組的契約:https ://github.com/Kuly14/Huff-Arrays/blob/main/src/DynamicArray.huff

它比上面的例子復雜一點,因為我們需要計算數組中有多少項才能不覆蓋任何變數。

我還沒有時間為它創建任何測試,所以請記住這一點。

如果您想將變數一起打包到同一個插槽中以節省氣體,它會變得更加複雜。你必須做很多字節屏蔽。

這是 noxx 關於該主題的一篇精彩文章:https ://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-3ea

這裡還連結到更深入解釋的文件:https ://docs.soliditylang.org/en/v0.8.13/internals/layout_in_storage.html#bytes-and-string

引用自:https://ethereum.stackexchange.com/questions/132979