什麼是 EVM?
Ethereum Virtual Machine(EVM,Ethereum 虛擬機)是一套執行智能合約的共同規則。Ethereum 節點使用各自的軟體實作這些規則,對相同交易和起始狀態進行計算,從而得到可由其他節點複核的結果。
EVM 不是某一台實體伺服器,也不是開發者在電腦上看到的單個應用。它更像一份精確的計算說明:程式碼能執行哪些基本操作、資料放在哪裡、每項操作消耗多少計算資源,以及執行成功或失敗時怎樣更新區塊鏈狀態。
從原始碼到可執行位元組碼
開發者通常使用 Solidity 等高階語言編寫合約。人類可讀的原始碼需要經過編譯器轉換為 EVM 能執行的位元組碼,也就是一串按固定格式排列的機器指令。
部署合約時,建立交易包含用於生成合約的程式碼。執行成功後,網路為合約建立地址,並保存之後接收呼叫時要執行的位元組碼。合約部署後的執行程式碼與開發者的原始檔並不是同一種表示,因此公開原始碼還需要與鏈上位元組碼核對,才能說明兩者對應。
編譯器版本和設定可能影響最終位元組碼。兩個看起來相似的原始檔也可能生成不同結果;看到同一個合約名稱,更不能代替對網路和合約地址的核對。
呼叫為合約提供執行輸入
使用者呼叫合約時,會向合約地址發送一筆帶有資料的交易。資料通常說明要呼叫哪個功能,並按約定格式附上參數。合約也可以在執行過程中呼叫另一個合約,把數值或資料繼續傳遞下去。
EVM 從目前區塊鏈狀態開始,讀取呼叫者、目標、附帶數值、輸入資料和目前區塊允許使用的資訊,然後逐條執行目標合約的位元組碼。每條指令都會按規則改變本次計算中的暫時資料,或請求讀取、寫入合約的持久狀態。
合約不會因為時間到了就自行啟動。必須有交易或其他合約呼叫形成執行入口;網頁上的「自動執行」通常還需要某個外部服務在條件滿足時提交交易。
操作碼是位元組碼中的基本動作
EVM 位元組碼由一項項操作碼組成。操作碼可以理解為虛擬機認識的最小動作,例如做算術、比較數值、讀取呼叫資料、讀取或寫入儲存,以及呼叫其他合約。
不同操作碼具有明確的輸入、輸出和 Gas 消耗規則。節點不需要理解合約的業務名稱,只需按操作碼順序執行,就能檢查另一個節點給出的結果是否符合協議。
高階語言中的一行程式碼可能被編譯成多條操作碼。反過來,只看某個操作碼也無法理解完整業務意圖,因此合約審查通常還要結合原始碼、編譯設定、呼叫資料和實際部署地址。
暫時資料與持久狀態
執行過程中使用的資料並不都會永久寫入區塊鏈。可以先區分三類位置:
- 呼叫資料是本次呼叫帶入的唯讀輸入;
- 記憶體是本次執行期間使用的暫時工作區,執行結束後不會保留;
- 儲存屬於具體合約,成功寫入後會成為區塊鏈狀態的一部分,供以後呼叫讀取。
EVM 還使用一種後進先出的暫時計算結構,稱為堆疊。操作碼從堆疊頂端取值、完成計算後再放回結果。一般讀者不必手工追蹤每一步,但需要知道「記憶體中的變化」和「合約儲存已經改變」不是同一件事。
寫入持久儲存通常比只做暫時計算消耗更多 Gas。刪除或改變儲存也受協議規則約束,不能把鏈上狀態當成普通程式可以任意覆蓋的本機檔案。
狀態變化必須能夠重複計算
同一區塊中的交易有確定順序。節點從相同的區塊前狀態開始,按順序執行相同交易,就應得到相同的區塊後狀態;否則它們無法對共同帳本達成一致。
因此,EVM 合約不能在執行時直接存取任意網頁、裝置時間或某台伺服器的隨機結果。需要鏈下價格、天氣或其他資訊時,外部參與者必須先把資料以交易形式帶到鏈上。EVM 能檢查程式碼怎樣使用這份輸入,卻不能自動證明輸入對應的鏈下事實真實。
區塊提供的時間、區塊編號等資訊也來自協議定義的執行環境。開發者可以按規則讀取它們,但不應把這些值誤當成不受區塊提議過程影響的精密外部時鐘或秘密隨機源。
Gas 限制每次執行的工作量
每項 EVM 操作都會消耗一定 Gas。Gas 是對計算和儲存工作的計量單位,不是一種獨立代幣;在 Ethereum 主網上,實際執行費用通常使用網路原生資產 ETH 支付。
交易發送方會設定允許本次交易最多消耗的 Gas。執行時,EVM 按實際執行的操作累計 Gas;若剩餘 Gas 不足以完成下一步,執行會因耗盡 Gas 而失敗。
Gas 讓無限迴圈或異常複雜的呼叫不能無成本佔用所有節點的計算資源。它也意味著同一個功能可能因輸入、目前狀態和執行路徑不同而消耗不同數量。交易金額大,不一定比金額小的交易執行更多程式碼。
成功、回退與失敗
合約可以正常結束並回傳資料,也可以主動回退,或因無效操作、Gas 耗盡等原因失敗。失敗時,本次呼叫路徑中尚未提交的狀態修改會按規則撤銷,但交易已經消耗的計算資源仍可能產生費用。
一個交易可以觸發多層合約呼叫。如果內層呼叫失敗,外層合約可以按程式碼選擇繼續處理回傳結果,也可能讓整個交易回退。因此,「某個內部步驟失敗」與「整筆交易最終失敗」需要結合呼叫結果判斷。
狀態回退也不會撤銷交易已經被納入區塊這一事實。區塊瀏覽器可以顯示失敗交易和消耗的 Gas,只是預期的合約狀態修改沒有生效。
讀取結果與提交交易
錢包或應用可以讓某個節點在本機模擬執行唯讀請求,並立即回傳結果。這類讀取不會由整個網路達成新的共識,也不會修改鏈上狀態,通常不需要使用者簽署並支付鏈上費用。
需要改變狀態的操作則必須形成交易、由帳戶簽署並廣播,在進入區塊後由節點共同執行。交易提交前的模擬可以幫助發現明顯失敗,但最終結果仍可能受交易排序、狀態變化、Gas 設定和所選網路影響。
因此,應用介面顯示「預計成功」不等於交易已經確認。真正的鏈上結果需要查看正確網路上的交易狀態、執行結果和合約狀態。
EVM 與 Ethereum 不是同一個概念
EVM 只描述智能合約執行和狀態轉換的一部分規則。Ethereum 還包括帳戶與交易格式、區塊傳播、權益證明共識、網路通訊和其他協議組成。
其他區塊鏈也可以實作 EVM 或與其高度相似的執行環境,以重用合約工具和位元組碼。它們通常被稱為 EVM 相容網路,但仍擁有獨立的區塊歷史、驗證安排、費用資產和安全邊界。
所以,「能執行 EVM 合約」不表示它就是 Ethereum,也不保證同一地址在不同網路上部署著相同程式碼。跨網路使用應用時,仍需核對網路及其網路編號、合約地址和實際位元組碼。
共同執行不等於合約安全
EVM 的確定性規則可以讓節點複核合約是否按程式碼執行,卻不能判斷程式碼是否符合使用者真正想要的業務結果。錯誤權限、外部合約在前一次操作結束前反覆回呼、價格輸入問題、升級控制或介面誘導,都可能讓一筆完全符合 EVM 規則的交易造成意外後果。
編譯成功、鏈上執行成功或原始碼公開,也不能分別替代安全審查。判斷具體合約時,需要結合已部署位元組碼、初始化狀態、管理權限、外部依賴和真實呼叫路徑。
常見問題
EVM 是一台雲端伺服器嗎?
不是。它是一套由節點軟體共同實作的執行規則,不對應某一台固定機器。
Solidity 程式碼會被 EVM 直接執行嗎?
通常不會。Solidity 原始碼先由編譯器轉換為 EVM 位元組碼,節點執行的是部署後的位元組碼。
讀取合約一定需要支付 Gas 費嗎?
本機唯讀請求通常不會形成鏈上交易,因此不會直接產生鏈上費用。如果讀取是另一筆上鏈交易執行過程的一部分,相關操作仍會計入該交易的 Gas。
EVM 能直接讀取網際網路資料嗎?
不能。外部資料需要由某個參與者或服務透過交易帶到鏈上,EVM 只能按規則處理已經提供的輸入。
EVM 相容就代表合約可以無修改遷移嗎?
不保證。相容程度、協議版本、可用操作碼、費用規則、系統合約和外部依賴可能不同,仍需在目標網路驗證和測試。
相關詞條
繼續了解Ethereum、智能合約、Gas 費和區塊鏈,或返回加密貨幣術語表。
參考來源
- Ethereum.org:Ethereum Virtual Machine——EVM、狀態轉換、執行環境、堆疊、記憶體和儲存。
- Ethereum.org:智能合約結構——原始碼、編譯、部署程式碼和合約呼叫結構。
- Ethereum.org:EVM 操作碼——操作碼、參數與 Gas 規則。
- Ethereum.org:Gas 與費用——Gas 計量、Gas 上限、執行費用和耗盡 Gas 的結果。




