Arrays
將數據追加到儲存陣列中
如何將數據附加到儲存陣列中?
例如,假設我們從一個看起來像這樣的數組開始:
[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