Contract-Development
智能合約的儲存是如何工作的?
我一直聽說,對於每個契約,都有一個儲存為連續數組(具有恆定的 O(1) 查找),有 2^256 個插槽,每個 32 字節,可用。但它在物理上不可能是真的。它是如何在實踐中真正實施的?謝謝。
是的,所採用的陣列在各個方面都是虛擬的。只需假設該數組是用零初始化的。由於儲存非常昂貴,我們不需要任何零。除非使用者明確定義。
一個鍵/值儲存映射
32-byte keys
將32-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]
正文是本文的摘要。