深入探討以太坊虛擬機 (EVM)

作者:Gimer Cervera,以太坊智能合約開發者 翻譯:善歐巴,比特鏈視界

介紹

本文深入探討以太坊虛擬機 (EVM)和Solidity Assembly,以實現智能合約優化和安全性。

以太坊虛擬機(EVM)是以太坊網絡的核心組件。EVM 是一款軟體,允許部署和執行用高級語言(例如 Solidity)編寫的智能合約。編寫合約後,將其編譯為字節碼並部署到EVM。EVM 運行在以太坊網絡的每個節點上。

Solidity Assembly 是一種低級程式語言,允許開發人員在更接近 EVM 本身的級別編寫代碼。它提供了對智能合約執行的更精細的控制,允許僅通過更高級別的 Solidity 代碼無法實現的優化和定製。

Solidity 中用於內聯彙編的語言稱為Yul。該程式語言充當編譯為 EVM 字節碼的中介。它被設計為一種低級語言,使開發人員能夠更細粒度地控制智能合約的執行。它可以在獨立模式下使用,也可以在 Solidity 中進行 內聯彙編 。Yul 被設計為一種基於低級堆棧的語言,使開發人員能夠編寫更優化、更高效的代碼。在解釋 Solidity 組裝之前,我們需要了解 EVM 的組件如何工作。

EVM 是一個 準圖靈完備的 狀態機。在這種情況下,術語 「準」 意味著流程的執行僅限於有限數量的計算步驟,具體取決於任何給定智能合約執行可用的 Gas 量。這就是以太坊處理停止問題和執行可能(惡意或意外)永遠運行的情況的方式。這樣就避免了以太坊平臺全面癱瘓的情況。

Gas是一個衡量在以太坊中完成交易所需的計算量的概念。交易成本以以太幣支付,並與 Gas 和 Gas 價格相關。我們在此過程中的目標是學習如何在不影響安全性的情況下最大限度地減少消耗的Gas總量。

代碼優化問題

內聯彙編是一種在較低級別訪問 EVM 的方法。它繞過了 Solidity 的幾個重要的安全功能和檢查。正確使用內聯彙編可以顯著降低執行成本。但是,您應該僅將其用於需要它的任務,並且僅當您知道自己在做什麼時。使用內聯彙編優化代碼可能會給您的代碼帶來新的安全問題。要掌握內聯彙編,我們需要了解 EVM 及其組件的工作原理。

在EVM中,每次第一次訪問任何存儲變量時都必須付費,這稱為 「冷」 訪問,需要花費2100個gas。第二次或連續一次被稱為 「熱」 訪問,需要花費 100 Gas。

以下代碼是我們如何使用 Yul 優化代碼的示例。函數 SetData1 以傳統方式使用 Solidity為全局變量 值設置新值。 我們第一次分配這個新值時需要花費 22514 個gas。第二個花費要少得多,即 5414 Gas。

okS662ywe9UkmCKVxHjWe0i81keFEhE51fLqNKWs.png

函數 setData2 實現內聯彙編。內聯彙編塊由 assembly { … } 標記,其中大括號內的代碼是 Yul 語言的代碼。此時無需了解原始碼,只需記住該軟體正在較低級別訪問存儲空間即可。因此,執行成本會更低。

在我們的示例中,第一次修改該值將花費 22484 個 Gas。連續幾次,成本為 5384 Gas。差異可能看起來並不顯著,但是我們應該考慮到這段代碼可能會執行數千次。

ZlEcJa5qttwq275Wh8CSJLzQvYgFSEUD9OuI4tp3.png

為什麼存儲這麼貴? 請記住,我們處於一個去中心化的世界,數據不僅僅存儲在一個地方,而是存儲在數以萬計的節點上。如果未來的交易需要訪問或更改它,它還必須可供網絡中的每個節點輕鬆使用。該數據的總體成本等於其消耗的存儲空間和在整個網絡上生成該數據的計算量的總和。

EVM 堆棧、存儲和內存

EVM 是一種基於堆棧的機器,它在稱為堆棧的數據結構上運行,該結構保存值並執行操作。EVM 有自己的一組指令(稱為操作碼),用於執行讀取和寫入存儲、調用其他合約以及執行數學運算等任務。堆棧按照 後進先出 (LIFO) 方式運行,請參見圖 1,這意味著最近插入的項存儲在堆棧的頂部,並且是第一個要刪除的項。

ErTKbn1SRoeL6bCljlu7WoUgpf9Cw4tKmpq5xTLT.png

當執行智能合約時,EVM 創建一個包含各種數據結構和狀態變量的執行上下文。執行完成後,執行上下文將被丟棄,為下一個合約做好準備。在執行期間,EVM 會維護一個臨時內存,該內存在事務之間不會持續存在。EVM 執行深度為 1024 項的堆棧機。每個項目都是一個 256 位字,選擇此大小是為了便於使用 256 位哈希和橢圓曲線加密。

EVM 具有以下組件,見圖 2:

  • 堆棧:EVM 的堆棧是一種按後輸入先輸出 (LIFO) 方式運行的數據結構,用於在智能合約執行期間存儲臨時值。

  • 存儲:永久存儲,是以太坊狀態的一部分,僅在第一次初始化為零。

  • 內存:易失性、動態大小的字節數組,用於存儲合約執行期間的中間數據。每次創建新的執行上下文時,內存都會初始化為零。

  • Calldata:這也是一個易失性數據存儲區域,類似於內存。然而它存儲不可變的數據。它旨在保存作為智能合約交易的一部分發送的數據。

  • 程序計數器:程序計數器 (PC) 指向 EVM 要執行的下一條指令。PC通常在一條指令執行後增加一個字節。

  • 虛擬ROM:智能合約作為字節碼存儲在該區域中。虛擬 ROM 是只讀的。

byS0PEfxE9E3EAlqlseO5P36kgSUAJ4RXlEpWJxG.png

EVM 堆棧

在該架構中,程序的指令和數據保存在內存中,程序的執行由指向堆棧頂部的 堆棧指針控制。 堆棧指針跟蹤下一個值或指令將在堆棧上保存或檢索的位置。當程序運行時,它將值添加到堆棧中並對已經存在的值執行操作。當代碼想要將兩個數字相加時,它將數字壓入堆棧,然後對頂部的兩個值執行加法操作。然後結果返回到堆棧。

SLyBgI6MX0FvAU6B3i9jQkAvd9V1ACc7FR1Mlkp3.png

基於堆棧的架構最重要的特徵之一是它允許高度簡單且高效的操作執行。由於堆棧是一種 LIFO 數據結構,因此可以輕鬆快速地處理數據和指令。

EVM 有自己的一組指令,稱為操作碼。操作碼用於執行讀取和寫入存儲、調用其他合約以及執行數學運算等任務。EVM 指令集提供您可能期望的大部分操作,包括:

  • 堆棧操作:POP、PUSH、DUP、SWAP

  • 算術/比較/按位:ADD、SUB、GT、LT、AND、OR

  • 環境:CALLER、CALLVALUE、NUMBER

  • 內存操作:MLOAD、MSTORE、MSTORE8、MSIZE

  • 存儲操作:SLOAD、SSTORE

  • 程序計數器相關操作碼:JUMP、JUMPI、PC、JUMPDEST

  • 停止操作碼:STOP、RETURN、REVERT、INVALID、SELFDESTRUCT

EVM存儲

EVM 存儲是非易失性空間,保存 256 位 –> 256 位的鍵值對。合約中的存儲槽位總數為 2²⁵⁶,這是一個非常龐大的槽位數量。區塊鏈上的每個智能合約都有自己的存儲空間。

在函數調用期間,存儲用於在函數調用之間需要記住的數據。它用於存儲即使在智能合約執行結束後也需要可用的變量和數據結構。

1HMGlMM7NtpaHHsnMiAq1AEaILWPXt4dG3VwqyKy.png

訪問存儲的操作碼是:SLOAD 和 SSTORE

該帳戶的存儲是永久數據存儲,僅由智能合約使用。外部擁有的帳戶 (EOA) 將始終沒有代碼且存儲空間為空。

EVM內存

內存是架構中的易失性內存,其數據在區塊鏈中不持久。內存是一種隨機訪問數據結構,在智能合約執行期間存儲臨時數據。

S3MF42KoITdlBytrmQc3NNV8NNmTkTWz2DqDUO1A.png

內存分為四部分:2 個槽用於暫存空間,1 個槽用於空閒內存指針,0 槽和 1 個槽指向可用的空閒內存。前 64 個字節的空間將由散列方法使用,散列方法在最終返回最終輸出之前需要臨時空間來存儲中間輸出。

空閒內存指針只是指向空閒內存開始位置的指針。它確保智能合約跟蹤哪些內存位置已被寫入以及哪些仍然可用。這可以防止合約覆蓋已分配給另一個變量的某些內存。圖 6 顯示了內存是如何劃分的:

g3imQHTd89wyatS2hNwKZHK4Ys4SANntyutufP7c.png

內存用於存儲不需要保存在存儲器中的變量和數據結構。智能合約執行期間可以調整內存大小,但訪問速度比堆棧更慢且成本更高。

考慮內存是零初始化的,用於訪問內存的操作碼是:MLOAD、MSTORE、MSTORE8

概括

在本文中,我們回顧了與以太坊虛擬機(EVM)相關的一些基本概念。實現內聯彙編代碼需要深入了解 EVM。這是因為我們正在與 EVM 的一些組件進行交互。在以後的課程中,我們將更詳細地分析其他 EVM 元素,例如:存儲、內存和 Calldata。此外,我們還將回顧字節碼、Gas 和應用程式二進位接口 (ABI) 等重要概念。最後,我們將討論操作碼的工作原理以及更多內聯彙編示例,以安全地優化智能合約的執行。

  • Related Posts

    速覽Binance HODLer最新空投項目Particle Network

    資料來源:幣安官網、Particle Network官網、白…

    以太坊沒落 PVP盛行 懷念2020年的夏天

    Jessy( @susanliu33 ),比特鏈視界 Vit…

    發佈留言

    發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

    You Missed

    歷史性轉折:比特幣正在成為避險資產

    • By jakiro
    • 19 4 月, 2025
    • 0 views
    歷史性轉折:比特幣正在成為避險資產

    是什麼讓加密貨幣rug pull事件頻發?

    • By jakiro
    • 18 4 月, 2025
    • 4 views
    是什麼讓加密貨幣rug pull事件頻發?

    Wintermute Ventures:我們為什麼投資Euler?

    • By jakiro
    • 18 4 月, 2025
    • 4 views
    Wintermute Ventures:我們為什麼投資Euler?

    川普可以將鮑威爾炒魷魚嗎?會帶來什麼經濟風險?

    • By jakiro
    • 18 4 月, 2025
    • 6 views
    川普可以將鮑威爾炒魷魚嗎?會帶來什麼經濟風險?

    Glassnode:我們正在經歷牛熊轉換嗎?

    • By jakiro
    • 18 4 月, 2025
    • 5 views
    Glassnode:我們正在經歷牛熊轉換嗎?

    The Post Web加速器首批8個入選項目速覽

    • By jakiro
    • 17 4 月, 2025
    • 9 views
    The Post Web加速器首批8個入選項目速覽
    Home
    News
    School
    Search