以太坊如何最佳化儲存以節省空間並降低燃氣費

買賣虛擬貨幣

為了解決這個問題,讓我們深入瞭解以太坊如何最佳化資料儲存。但首先,請確保您知道如何讀取區塊鏈上的儲存空間。

以太坊如何最佳化資料儲存

從Solidity文件中,我們得到了這個定義:

靜態大小的變數(除了對映和動態大小的陣列型別之外的所有內容)在從位置0開始的儲存中連續佈局。如果可能,需要少於32個位元組的多個專案被打包到單個儲存槽中,根據以下規則

以下是低效儲存使用的示例。請注意較小的大小變數(如boolVar和bytes4Var)不是按順序初始化的,當它們可以打包在一起時會佔用新的插槽0和2:

更有效的儲存方法是按順序宣告bool(1位元組大小)和bytes4(4位元組大小)變數。然後,EVM將這兩個模組有效地打包到一個儲存插槽中。

同樣,在Object結構中,更有效的方法是將兩個uint8組合在一起,佔用1個插槽。這樣,Object的所有未來例項只需要儲存2個插槽,而不是3個插槽。儲存最佳化在結構中尤其重要,因為儲存可以快速增長:

注意:插槽索引為0從右到左。Bytes4Var在boolVar之後被初始化,所以它儲存在boolVar的左邊,正好是1個位元組。

例外情況:

1、常量不儲存在儲存器中。從以太坊文件中,編譯器不為常量變數保留儲存槽。這意味著您將無法在任何儲存槽中找到以下內容:

contract A {
    uint public constant number = ...; //not stored in storage
}

2、對映和動態大小的陣列不遵循這些約定。稍後將詳細介紹這一點。

你現在有能力解決這個問題!

詳情演練

要解決這個級別的問題,您必須找出資料[2]中儲存的內容,將其轉換為bytes16變數,並將其作為unlock()privacy.sol的金鑰提交。

0.注意privacy.sol中的以下變數宣告。讓我們來計算一下這些佔用的儲存插槽:

// boolean values take up 1 byte
bool public locked = true;

// IGNORE: as constant uints are not stored in storage
uint256 public constant ID = block.timestamp;

// uint8 vars take up 1 byte
uint8 private flattening = 10;
uint8 private denomination = 255;

// uint16 takes up 2 bytes
uint16 private awkwardness = uint16(now);

// each bytes32 takes up one slot
// so an array of length 3 takes up are 3 slots
bytes32[3] private data;

你應該期望unlock、flattening和denomination三個欄位一共佔用5個位元組,僅共享1個儲存槽(備用27個位元組的空閒儲存空間)。

您應該期望data陣列佔用3個剩餘的插槽,每個資料有一個data[index]。

1、要獲取資料[2],請讀取插槽4的儲存:
在Truffle控制檯-Network Ropsten中,訪問您的級別例項,並呼叫GetStorageAt(…,3)獲取資料[2]。

2、使用Remix,將bytes32結果轉換為bytes16值。
3、使用Remix,使用bytes16值呼叫unlock()來解鎖此級別!

關鍵安全要素:

· 通常,過多的插槽使用會浪費gas,特別是如果您宣告瞭將複製許多例項的結構。請記住最佳化儲存以節省gas!
· 如果您不需要保持智慧合約狀態,請將變數儲存到memory中。SSTORE <> SLOAD是非常耗氣的操作碼。
· 所有儲存在區塊鏈上都是公開可見的,甚至是您的private變數!
· 不要在沒有雜湊的情況下儲存密碼和私鑰

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;