Contract-Development

智能合約的儲存是如何工作的?

  • June 13, 2020

我一直聽說,對於每個契約,都有一個儲存為連續數組(具有恆定的 O(1) 查找),有 2^256 個插槽,每個 32 字節,可用。但它在物理上不可能是真的。它是如何在實踐中真正實施的?謝謝。

是的,所採用的陣列在各個方面都是虛擬的。只需假設該數組是用零初始化的。由於儲存非常昂貴,我們不需要任何零。除非使用者明確定義。

一個鍵/值儲存映射32-byte keys32-byte values很好地完成這項工作。不存在的鍵被簡單地定義為映射到零值。因為零不佔用任何空間,所以可以通過將值設置為零來回收儲存。當您將值更改為零時,這會在智能合約中通過 gas 退款得到激勵。

固定大小的值

對於具有固定大小的已知變數,只給它們保留儲存位置是有意義的

contract StorageTest {
   uint256 a;
   uint256[2] b;

   struct Entry {
       uint256 id;
       uint256 value;
   }
   Entry c;
}

這些插槽是在編譯時確定的,嚴格基於變數在合約程式碼中出現的順序。

定位動態大小的值 對於像映射這樣的動態大小的值,Solidity 使用雜湊函式統一且可重複地計算動態大小的值的位置。

contract StorageTest {
   uint256 a;     // slot 0
   uint256[2] b;  // slots 1-2

   struct Entry {
       uint256 id;
       uint256 value;
   }
   Entry c;       // slots 3-4
   Entry[] d;
}

在上面的程式碼中,動態大小的數組 d 位於插槽 5,但唯一儲存在那裡的是 d 的大小。數組中的值從槽的雜湊開始連續儲存。

映射

映射需要一種有效的方法來找到與給定鍵對應的位置。散列密鑰是一個好的開始,但必須注意確保不同的映射生成不同的位置。

在上面的程式碼中,e 的“位置”是插槽 6,f 的位置是插槽 7,但在這些位置實際上沒有儲存任何內容。(沒有要儲存的長度,單個值需要位於其他位置。)

為了在映射中查找特定值的位置,鍵和映射的槽被散列在一起。

複雜類型的組合

動態大小的數組和映射可以遞歸地相互嵌套。發生這種情況時,通過遞歸應用上面定義的計算來找到值的位置。這聽起來比實際更複雜。

例如:g[123][0]

正文是本文的摘要。

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