瞭解區塊鏈虛擬機器:EVM、HVM、WASM、MOVE

BSN研習社發表於2023-01-06
在區塊 鏈上,使用者透過執行部署在區塊鏈上的合約,完成需要共識的操作。 而為智慧合約提供執行環境的便是對應的虛擬機器。

EVM

基礎概念

EVM,是ERC協議和運作的心臟。

簡單的類比: EVM之於以太坊,正如Java虛擬機器之於Java語言

我們寫的java程式碼會被編譯成位元組碼,但計算機無法識別位元組碼;java虛擬機器把位元組碼編譯成計算機系統可以識別的機器碼指令,然後在計算機上執行。如下圖所示:

EVM的存在是為了能讓我們用Solidity編寫的合約程式碼,執行在以太坊的環境中。 這樣類比的話,以太坊就相當於計算機環境,EVM把合約程式碼編譯成以太坊能識別的機器碼執行。 如下圖所示:

大致流程:

當智慧合約被編譯成二進位制檔案後,被部署到區塊鏈上。使用者透過呼叫智慧合約的介面,來觸發智慧合約的執行操作。EVM執行智慧合約的程式碼,修改當前區塊鏈上的資料(狀態)。被修改的資料,會被共識,確保一致性。

它實際上是完全隔離的,這意味著在EVM上執行的程式碼無法訪問網路、檔案系統和其他程式。智慧合約對其他的智慧合約的訪問權也有限,在區塊鏈網路上單獨運作。

編寫智慧合約有三個主要步驟:

  1. 用高階語言編寫,如Solidity

  2. 用EVM編譯器編譯成位元組碼

  3. 用客戶端上傳到區塊鏈網路

技術細節

EVM的儲存模型

EVM是一個基於堆疊的虛擬機器,具有臨時記憶體位元組陣列和持久鍵值儲存(持久儲存在Storage中)。

Stack: EVM是基於棧(stack)的虛擬機器,stack用來儲存指令的輸入輸出資料,最大深度為1024個字,其中每個單元就是一個字。

臨時儲存Memory: 記憶體,一個簡單的記憶體陣列,用於臨時儲存EVM程式碼執行中需要存取的各種資料,基於字進行定址和擴充套件

永久儲存Storage: 用來儲存所有合約“狀態”的永久儲存,由以太坊客戶端獨立維護,每個賬戶的儲存區域被以“字”為單位劃分為若干個“槽”(solt),合約中的狀態變數會根據其具體型別分別儲存到這些槽中。例如在合約建立時由EVM根據合約定義的狀態變數進行初始化,將他們儲存進以“字”為單位劃分的“儲存槽(solt storage)”中。

Storage也是作為是世界狀態的一部分存在的,客戶端會用一個MPT來維護其資料。

ROM: 用來儲存所有EVM程式程式碼的只讀儲存,由以太坊客戶端獨立維護。

交易在EVM的執行

輸入一筆交易,內部會轉換成一個Message 物件,傳入EVM執行。

普通轉賬交易

如果是一筆普通轉賬交易,那麼直接修改StateDB中對應的賬戶餘額即可。

智慧合約的建立或者呼叫

如果是智慧合約的建立或者呼叫,則透過EVM中的直譯器載入和執行位元組碼,執行過程中可能會查詢或者修改StateDB。

1.生成Contract物件

交易會被轉換成一個Message物件傳入EVM,而EVM則會根據Message生成一個Contract物件以便後續執行。

2.送入直譯器執行

EVM是基於棧的虛擬機器,直譯器中需要操作四大元件

PC: 類似於CPU中的PC暫存器,指向當前執行的指令

Stack: 執行堆疊,位寬為256bits,最大深度為1024

Memory: 記憶體空間

Gas: 油費池,耗光油費則交易執行失敗

EVM的每條指令稱為一個OpCode,佔用 一個位元組,所以指令集最多不超過256

  • 首先PC會從合約程式碼中讀取一個OpCode

  • 然後從一個JumpTable中檢索出對應的operation,也就是與其相關聯的函式集合

  • 接下來會計算該操作需要消耗的油費,如果油費耗光則執行失敗,返回ErrOutOfGas錯誤。如果油費充足,則呼叫execute()執行該指令,根據指令型別的不同,會分別對Stack、Memory或者StateDB進行讀寫操作。

EVM機器語言

EVM機器語言分為特定的指令集組,例如算術運算,邏輯和比較運算,控制流,系統呼叫,堆疊操作和儲存器操作。除典型的Bytecode操作外,EVM還必須管理帳戶資訊(即地址和餘額),當前gas價格和區塊資訊。

通用堆疊操作

    POP // 專案出棧
    PUSH // 專案入棧
    MLOAD // 將專案載入到記憶體中
    MSTORE // 在記憶體中儲存專案
    JUMP // 改變程式計數器的位置
    PC // 程式計數器
    MSIZE // 活動的記憶體大小
    GAS // 交易可用的gas數量
    DUP // 複製棧專案
    SWAP // 交換棧專案

    通用系統操作

      CREATE // 建立新的帳戶
      CALL // 在帳戶間傳遞訊息的指令
      RETURN // 執行停機
      REVERT // 執行停機,恢復狀態更改
      SELFDESTRUCT // 執行停機,並標記帳戶為刪除的

      算術運算

        MUL //乘法
        SUB //減法
        DIV //整數除法
        SDIV //有符號整數除法
        MOD // Modulo(剩餘)操作
        SMOD //簽名模運算
        ADDMOD //模數加法
        MULMOD //模數乘法
        EXP //指數運算
        STOP //停止操作

        環境操作碼

          ADDRESS //當前執行帳戶的地址
          BALANCE //帳戶餘額
          CALLVALUE //執行環境的交易值
          ORIGIN //執行環境的原始地址
          CALLER //執行呼叫者的地址
          CODESIZE //執行環境程式碼大小
          GASPRICE //gas價格狀態
          EXTCODESIZE //帳戶的程式碼大小
          RETURNDATACOPY //從先前的記憶體呼叫輸出的資料的副本

          與現有的虛擬機器科技作比較

          • 虛擬機器(Virtual Machine)

          • Java 虛擬機器(VM)

          虛擬機器技術與EVM的不同之處在於它們的目的是提供管理程式功能,或者處理客戶作業系統與底層主機作業系統和硬體之間的系統呼叫,任務排程和資源管理的軟體抽象。

          然而,Java VM(JVM)規範的某些方面確實包含與EVM的相似之處。從高階概述來看,JVM旨在提供與底層主機作業系統或硬體無關的執行時環境,從而實現各種系統的相容性。在JVM上執行的高階程式語言(如Java或Scala)被編譯到相應的指令集Bytecode 中。這與編譯要在EVM上執行的Solidity源檔案相當。

          EVM的幾個功能

          • 便於測試:為了保證各種“智慧合約”的順利執行,我們需要給它們建立一個安全的執行環境,EVM就是一個程式碼的執行環境。

            正如我們上文所說,在虛擬機器裡的各種操作不會影響主機一樣,任何想要在EVM建立智慧合約的開發者可以在虛擬機器上測試各種應用而不佔用主鏈資源也不受其他區塊鏈的影響。

          • 增加安全性:ETH上承載著具有強大功能的各種應用,其邏輯也就更加複雜,開發者也越容易出現各種漏洞。而EVM是一個完全獨立的沙盒,合約程式碼可對外完全隔離並在EVM內部執行。

            不僅可以防止因為不法分子或者程式設計師的程式設計錯誤而影響整個主鏈,還可以防止執行智慧合約的物理裝置遭受攻擊。

          • 保障穩定性:由於EVM部署在ETH網路的每個節點,整個ETH網路的資料由眾多節點共同維護和更新,這保持了整個區塊鏈資料的一致性,這同樣也使ETH有極高的故障容錯性,保證零停機。

          EVM和公鏈的關係

          目前市面上主流的公鏈,大部分都相容EVM。

          為什麼這些鏈要做EVM相容呢?

          核心當然是以太坊在公鏈領域的影響力。目前市場上的各種公鏈此起彼伏,但是ETH依然是公鏈領域的龍頭。這些新興的公鏈需要利用以太坊引流,如果開發者可以把智慧合約直接無縫遷移到自己的鏈上,那就是最好的引流方式。

          在這些公鏈產生之前,以太坊的生態裡,EVM已經部署了大量的應用。如果你不相容這些應用,前進的道路必然是舉步維艱。

          下面這個圖是2022年5月31日的全球公鏈的市場份額:

          這個網站看到所有相容EVM的公鏈:

          HVM

          HVM介紹

          概述

          HVM為趣鏈科技首創支援Java語言的智慧合約執行引擎,支援符合Java編寫規範多種資料結構,內建資料表結構,可以實現業務資料視覺化,在保證智慧合約執行的安全性、確定性、可終止性的前提下,提供了一系列靈活的應用模式和工具方法集,以滿足複雜多樣的業務場景需求,為廣泛的區塊鏈開發人員提供更便捷、靈活、安全的區塊鏈應用開發模式。

          使用

          HVM合約執行的操作:從SDK呼叫一筆HVM的合約,首先需要共識模組將透過共識的區塊交易傳送給執行模組,然後執行模組呼叫HVM暴露出來的合約介面,最後合約執行完成後會將結果返回,將執行結果寫入賬本中。

          在架構層面,HVM自上而下主要分為三個部分:合約操作層、庫函式層以及虛擬機器層。

          1.虛擬機器層

          虛擬機器層主要是在合約執行過程中,對於合約解析執行的內部操作。為了提高整體的執行效率,HVM設計定製類載入器,類載入快取提供合約地址到合約類載入器的對映,一個合約類載入器儲存合約的位元組碼和合約類例項,採用最近最少使用淘汰策略(LRU)減少類重複載入帶來的開銷;指令解析從開始的每次對指令進行解析到將指令做成單例,並進行棧幀複用,大量節省指令執行時間,提高整體執行效率。

          2.庫函式層

          庫函式包括資料結構、賬本操作、日誌資訊以及加解密等功能。

          • 資料結構符合Java編寫正規化: HyperList、HyperMap為平臺 獨立研發,為了方便Java軟體開發者習慣,使其無需感知區塊鏈底層KV結構即可編寫相應業務邏輯程式碼。HyperMap和HyperList的使用類似於開發者所熟知的HashMap和ArrayList,但做了原創性地最佳化,在減少記憶體使用的同時也提高了更新賬本的插入效率。

          • 內建資料表結構: 為了滿足複雜業務場景下資料型別多樣化、業務資料視覺化與可分析的需求,智慧合約需要支援複雜的表結構資料組織形式。 HVM提供了內建資料結構HyperTable,支援在合約內部按照表的形式組織業務資料,便於業務資料視覺化以及後續的資料分析與價值挖掘。 這種結構可以讓原Solidity語言中複雜巢狀的資料操作簡單化,同時在效能方面,能有效解決序列化、反序列化造成的效能瓶頸,整體維護成本更低、使用更高效。

          • 內建巢狀Map資料結構: HyperList、HyperMap資料結構都無法滿足複雜資料組織結構的需求;HyperTable的表結構擁有嚴格的層級格式(表-行-列簇-列-值),缺乏在複雜結構下的靈活性(例如:不可只有列,沒有列簇)。針對上述問題,HVM推出新型的資料結構——NestedMap,支援使用者按需進行靈活的資料組織,並且實現對多層對映資料更高的讀寫效能。

          3.合約操作層

          這一層與使用者直接相關聯,主要包括合約部署、呼叫等全生命週期管理,對於合約的操作透過會對鏈上的合約資料狀態產生影響,所以平臺採取了靈活的合約管理提案申請-閾值投票-提案執行的策略,透過合約管理員對合約操作進行控制,保證合約管理操作的公平與安全。

          • 合約部署 : 編寫Java智慧合約,並透過SDK發交易的形式將其部署到區塊鏈上;

          • 合約呼叫 : 根據合約地址,呼叫相應合約中的邏輯。

          • 合約升級 : 需要對合約進行升級操作時,因為升級合約是一個鏈級操作(改變整個鏈上的狀態),所以需要採用CAF聯盟自治框架才可以進行合約升級,保證鏈上合約的安全控制。

          • 合約凍結/解凍 : 將鏈上的合約凍結,在合約所有者解凍之前,禁止任何人呼叫,凍結不同於銷燬,其具備一個可逆的過程,可以透過合約解凍的操作重新使用。

          • 合約銷燬 : 不同於合約凍結,合約銷燬是一個不可逆的操作,被銷燬的合約不能夠被訪問,不可以恢復,不允許再進行任何操作,但合約銷燬後的資料仍然會存在鏈的底層賬本中,僅用於監管審計。

          優勢

          • 支援多級日誌

          EVM未對出現的異常進行詳細定位,給編譯除錯造成極大的難度。而HVM透過內建日誌工具類,支援六種日誌級別:critical、error、warning、notice、info、debug。可以為每種常見的錯誤進行合理的提示,方便使用者對合作操作過程中產生的異常進行debug,方便開發和運維快速定位問題。

          • 分層呼叫模式

          HVM採取分層呼叫的模式,可以有效降低合約升級的成本。其實現方法主要透過InvokeBean的方式在業務呼叫層在不更新合約的情況下定義豐富的業務邏輯, 合約層只實現最核心、最基本的原子操作。以轉賬場景為例,合約層只有增加餘額和減少餘額的方法,在InvokeBean呼叫層定義轉賬的邏輯:如餘額是否充足、 減少轉讓方餘額和增加接收方餘額。

          • 支援加解密工具

          一些業務場景需要在智慧合約中進行簽名驗籤邏輯處理,從而進行身份認證,便於進行許可權判斷或者後續業務的開展。因此HVM設計了基於TEE的加解密工具, 支援在合約中呼叫儲存於TEE的公私鑰完成簽名、驗籤操作,並支援ECDSA國標系列、SM國密系列等多種加解密演算法,具有方便友好安全的特性。

          • 支援合約訪問控制

          合約編碼者可以透過智慧合約和訪問控制策略來限制訪問資料的角色和使用者,在合約中針對節點、角色、使用者定製不同的合約函式訪問許可權。合約編碼者可以在 合約中為一些高許可權的函式設定許可權控制,使得該函式只能被固定地址的呼叫者呼叫,從而實現訪問許可權控制。

          WASM

          WASM-VM簡介

          概述

          WebAssembly(wasm) 是一個基於二進位制操作指令的棧式結構的虛擬機器,wasm可以被編譯為機器碼,可以更快,更高效的執行本地方法和硬體資源,透過和js協作,前端可以實現更快,更復雜的計算和應用。

          不僅可以嵌入瀏覽器增強web應用,也可以應用於其他的場景。

          wasm支援高階語言程式設計,目前比較成熟的編譯器支援C \ C++ \Rust。

          工作原理

          WASM是一種不依賴於具體物理機器的組合語言,可以抽象的理解成它是概念的機器語言,而不是實際的物理機器語言,因此,WebAssembly指令也可稱為虛擬指令,可以更快的更直接的對映的到機器碼!

          優勢

          WASM虛擬機器已經被Google,Facebook,Microsoft等世界頂級網際網路公司同時支援,同時也可以在所有流行的瀏覽器中執行。WASM虛擬機器一開始設計的目的是用於解決Web程式日益嚴峻的效能問題,因其有以下優越的特性,被越來越多的非Web專案所採用。

          1. 快速、高效、可移植:透過利用常見的硬體能力,WASM程式碼在不同平臺上能夠以接近本地速度執行。

          2. 可讀、可除錯:WASM是一門低階語言,但是它有一種人類可讀的文字格式,這允許透過人工來寫程式碼、看程式碼以及除錯程式碼。

          3. 保持安全:WASM被限制執行在一個安全的沙箱執行環境中。像其他網路程式碼一樣,它遵循瀏覽器的同源策略和授權策略。

          4. 不破壞網路:WASM的設計原則是與其他網路技術和諧共處並保持向後相容。

          與EVM對比

          速度

          • EVM

          • 只能處理256位位元組碼,這意味著小於256位的位元組碼必須先轉換為256位格式,然後才能傳送給EVM。

          • EVM的可擴充套件性問題很明顯,因為它每秒只處理25個交易。

          • WASM

          • 直接轉換為編譯後的程式碼,這使它能夠更快地載入,同時增加每個區塊所處理的交易數量。

          預編譯

          • EVM

          • 依賴於預編譯(預編譯合約)。當發出預編譯呼叫時,EVM將執行預定義的本機程式碼,然後顯示結果。這些預編譯特定於用於基本操作的特定協議,例如簽名方案和雜湊。

          • 儘管預編譯在不消耗大量gas的情況下使加密計算變得高效,但它們也帶來了問題。引入新的預編譯器通常要求網路經歷一個系統範圍的硬分叉。

          • WASM

          • 消除了以太坊對預編譯合同的依賴。由於WASM非常高效,開發人員可以建立高效、快速的智慧合約,而無需擔心潛在的硬分叉。

          靈活性和互操作性

          WASM支援更多的語言,並且提供了比EVM更廣泛的工具集。WASM支援傳統語言,如Rust、C和c++。WASM也被本地JavaScript引擎支援,例如 Google 的 V8 引擎(基於Node.js 和 Chromium 的瀏覽器)、微軟的Chakra 引擎(Microsoft Edge)和Mozilla 的 Spidermonkey 引擎(Thunderbird和 Firefox)。

          MOVE

          概述

          MoveVM是具有靜態型別系統的堆疊機。MoveVM從幾個方面來約束 Move語言規範,包括混合檔案格式、驗證和執行時的約束。檔案格式的結構允許定義模組,型別(資源和非限制型別)和函式。程式碼透過位元組碼指令表示,位元組碼指令可以引用外部函式和型別。

          實現細節

          Move VM執行以Move位元組碼錶示的交易。它有兩個核心包:核心VM和VM執行時。

          MoveVM核心包提供檔案格式的定義以及與檔案格式相關的所有實用程式:

          • 一個簡單的Rust抽象檔案格式

            (libra/language/vm/src/file_format.rs) 和位元組碼。這些Rust結構廣泛用於程式碼庫中。

          • 檔案格式的序列化和反序列化。這些定義了程式碼的鏈上二進位制表示。

          • 一些漂亮的輸出展示功能。

          • 檔案格式的基本架構。

          • gas成本/綜合基礎設施。

          Move程式語言

          Move是一種新的程式語言,旨在為Libra區塊鏈提供安全可程式設計的基礎。

          Move與平臺無關,支援跨區塊鏈的共享庫、工具和開發人員社群。Move語言的設計強調安全性,旨在避免許多Web3.0使用者受害的情形,包括但不限於重入漏洞(re-entrancy vulnerabilities)、毒令牌(poison tokens)和欺騙性令牌批准(spoofed token approvals)等問題

          Move語言目錄由五個部分組成:

          • 虛擬機器 (VM), 它包含位元組碼格式、位元組碼直譯器和執行交易塊的基礎設施。該目錄還包含生成創世區塊的基礎設施

          • 位元組碼驗證器, 其中包含一個靜態分析工具,用於拒絕無效的Move位元組碼。虛擬機器在執行新的Move程式碼前,會先執行位元組碼驗證器。編譯器執行位元組碼驗證器則會把輸出和錯誤顯示給程式設計師。

          • Move中間層表示 (IR:intermediate representation) 編譯器, 它將可讀的程式文字編譯成Move位元組碼. 警告:IR編譯器是一個測試工具。它會生成將被Move位元組碼驗證器拒絕的無效位元組碼。IR語法工作仍在進行,或將經歷重大的變化。

          • 標準庫, 其中包含LibraAccount和LibraCoin等核心系統模組的Move IR程式碼。

          • 一些測試 ,用於虛擬機器,位元組碼驗證程式和編譯器。這些測試是用Move IR編寫的,由測試框架執行,該測試框架從註釋中編碼的特殊指令解析執行測試的預期結果。

          版權宣告:本文為CSDN博主「鯤志說」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。

          原文連結:

          https://blog.csdn.net/m0_37482190/article/details/128294434

          文章來源: CSDN博主「鯤志說」
          文章原標題:《 web3:智慧合約-虛擬機器(EVM、HVM、WASM、MOVE)

          如有侵權請與我們聯絡刪除。

          來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70012206/viewspace-2931083/,如需轉載,請註明出處,否則將追究法律責任。

          相關文章