Solidity

EVM 中記憶體、儲存和堆棧區域的使用

  • August 5, 2017

在solidity合約中,我可以理解基於可變的使用和昂貴,我可以確定應該使用哪一個(記憶體、儲存或堆棧)。但是我遇到了一些只能使用記憶體的情況,就像那樣。

所以我的問題是:

哪裡只能使用記憶體?哪裡只能使用儲存?哪裡只能使用堆棧?

我找不到任何說明在任何特定情況下都應使用特定區域的文件。

謝謝

貯存

讓我們首先考慮儲存。儲存非常昂貴。將儲存位置從零設置為一個值需要 20000 gas,更改其值需要 5000 gas。(您確實會因為將位置重置為 0 而獲得一些氣體。)原因是合約的儲存值永遠儲存在區塊鏈上,這具有現實世界的成本。讀一個單詞也需要 200 氣,而記憶需要 3 氣。

因此,對於儲存,僅在確實需要時才使用它。

什麼時候必須使用儲存?對於必須在不同合約呼叫之間持久化的值。例如,ERC20 代幣的賬戶餘額。儲存更新是合約的狀態更新,並非真正用於臨時數據。一個合約的儲存也可以被另一個合約讀取,或者通過查詢區塊鏈而不執行合約。

如果你願意,你可以把它想像成硬碟/SSD。儲存在電腦未執行時保留其價值。

記憶

記憶體相對比儲存便宜得多。讀取或寫入一個單詞需要 3 個 gas,如果你正在擴展記憶體,還需要一些 gas。對於幾 KB,它確實非常便宜,但是使用的越多,成本就會呈二次方增長:一兆字節的記憶體將花費幾百萬 gas。

但是,記憶體只能在合約執行期間訪問;一旦執行完成,其內容將被丟棄。

什麼時候應該使用記憶體?幾乎所有非永久性的。這是一般的主力。

您可以將其視為電腦的 RAM。當電腦不執行時它會消失。

將數據儲存在堆棧上的成本與記憶體相似。有時將記憶體地址推送到堆棧會減少成本;有時會有更多的成本,因為編譯器必須在堆棧上洗牌。該堆棧的最大容量為 1024 件,但只有頂部的 16 件易於訪問。如果您用完堆棧,則契約執行將失敗。編譯器通常將它用於計算中的中間值和其他臨時量。

總的來說,我會把堆棧留給編譯器來解決。

契約終止後堆棧也不會持續存在。


上面的所有資訊都埋在黃皮書裡——我已經讀過了,所以你不必:-)

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