1. 程式人生 > >如何設計一個比Ethereum和EOS更好的虛擬機器

如何設計一個比Ethereum和EOS更好的虛擬機器

以太坊虛擬機器(EVM)是一種“準圖靈完整”的256位虛擬機器,是以太坊網路最重要的組成部分之一。自以太坊以來,基於EVM的智慧合約開發逐漸完善,並出現很多DApp應用,例如以太貓以及最近異常火爆的Fomo3D遊戲等等。智慧合約以及虛擬機器的重要性已經得到了基本所有區塊鏈開發者的認同,因此虛擬機器的可用性、智慧合約開發的便捷性已經成為各大公鏈競爭的主要賽道,同時也會決定一條公鏈最終能達到的高度。

一、以太坊虛擬機器(EVM)並不圖靈完備

網路上對以太坊虛擬機器(EVM)有一種普遍的誤解,就是認為以太坊虛擬機器是圖靈完備的,然而並非如此。

圖靈機是阿倫圖靈在1936提出的數學模型。圖靈機包括一條無限長的紙帶,一個字元表,一個讀寫頭,一個狀態暫存器,一個有限的指令集。運算開始時,圖靈機讀寫頭從某一位置開始按照此刻的配置(當前所處位置和當前格子內容等)來一步步的對照著指令集去進行操作,直到狀態變為停止,運算結束。在計算領域,我們研究的一切問題都是計算問題,圖靈完備意味著任意可計算問題都可以被解決。程式語言或虛擬機器的本質都是一個圖靈機,某種程式語言或者虛擬機器是圖靈完備意味著它可以做到圖靈機能做到的所有事情,即可以解決所有的可計算問題。

而在以太坊虛擬機器的設計中,因為指令的計算受到gas的約束,所以這就限制了可完成的計算次數。這也是一種圖靈不完備的常見原因,因為迴圈、遞迴或計算的有界導致程式保證終止,所以EVM上能執行的程式會受到很多限制,EVM並不是圖靈完備的。

二、EVM的不合理設計

以太坊的EVM作為最早的準圖靈完備的虛擬機器,在開創了面向智慧合約的DApp開發的同時,隨著區塊鏈應用越來越廣泛,EVM最初的一些不合理設計逐漸顯現,甚至有些設計會導致嚴重的安全問題。單就以太坊虛擬機器層面,我們認為在設計層面和安全層面有以下這些問題:

01 智慧合約設計層面

缺乏標準庫支援:EVM缺少完善的標準庫支援,甚至最基本的string型別支援,在EVM中都很雞肋,例如字串拼接、切割、查詢等等都需要開發者自己實現。帶來的後果就是開發者需要關注更多非本身業務的零碎細節,不能專注本身業務開發。同時自行實現的類庫可能會因為時間、空間複雜度太高,消耗大量無謂的gas,又或者開發者從開源專案中借鑑相關類庫程式碼,但也會引入更多安全性方面的問題,加重合約程式碼審計的複雜度,亦是得不償失。
難以除錯和測試:EVM難以除錯和測試,EVM除了能丟擲OutOfGas異常之外,不會給開發者返回任何資訊,無法列印日誌、要做到斷點、單步除錯更是完全不可能。雖然event機制可以部分改善這個問題,但event機制的本身設計就決定了他不是一個優雅好用的除錯工具。
不支援浮點數:EVM不支援浮點數,以太坊以Wei為最小單位,只有整數,不支援其他粒度的計量,這種設計避免了引入浮點數導致的精度問題,但開發者在實際開發中,為了表示一個eth變數,就會在變數後面跟很多0,導致程式碼維護極度複雜。同時不可否認,浮點數在特定的場景下,還是有很大的利用價值的,不能一刀切直接放棄引入。
合約不能升級:EVM不支援合約升級,合約升級是智慧合約開發中的一個強需求,也是每一個合約開發者必須要考慮的問題,合約升級可以實現給現有合約打安全補丁、擴充套件現有合約功能等等。EVM完全不支援升級,開發者只能通過釋出新合約來解決這個問題,費時費力。

02 智慧合約安全層面

溢位攻擊,EVM的safeMath庫不是預設使用,例如開發者對solidity的uint256做計算的時候,如果最終結果大於uint256的最大值,就會產生溢位變為一個很小的數,這樣就產生了溢位漏洞。諸如BEC、SMT等相關幣種都遭受過溢位攻擊,帶來了極度嚴重都後果,BEC溢位漏洞如下:

重入攻擊,solidity一大特性是可以呼叫外部其他合約,但在將eth傳送給外部地址或者呼叫外部合約的時候, 需要合約提交外部呼叫。如果外部地址是惡意合約,攻擊者可以在Fallback函式中加入惡意程式碼,當發生轉賬的時候,就會呼叫Fallback函式執行惡意程式碼,惡意程式碼會執行呼叫合約的有漏洞函式,導致轉賬重新提交。最嚴重的重入攻擊發生在以太坊早期,即知名的DAO漏洞。下面合約片段具體闡述了重入攻擊:

非預期函式執行, EVM沒有嚴格檢查函式呼叫,如果合約地址作為傳入引數可控,可能導致非預期行為發生。具體如下:

綜上,EVM在設計和安全層面都存在不少問題,雖然EVM團隊又開發出了Vyper這種新的合約開發語言,但一直處於實驗階段,不能實際生產使用。在以太坊被大規模應用到DApp開發的今天,各種問題不斷累積將最終導致其積重難返。

三、現象級公鏈EOS的明顯問題

EOS是繼以太坊之後,又一現象級的公鏈應用,有自己獨立的一套基於WebAssembly的智慧合約引擎,但目前EOS合約開發有如下幾個明顯問題:

賬戶系統不友好:建立賬戶操作難度大,建立賬戶後才能釋出合約,EOS需要使用已有賬戶去建立新賬戶,尋找一個擁有EOS賬戶的朋友或第三方,對任何人來說都不是一件很容易的事。建立賬號需要購買RAM,就是需要花錢建賬號,如果找第三方幫忙建立賬號存在資金風險。建立賬號後,還需要抵押EOS換取CPU使用時間和net頻寬,才能在EOS網路做操作。這些操作對於開發者來說過於繁瑣。
RAM價格:RAM價格昂貴,合約執行必須用到RAM,EOS開通了RAM市場,用於交易記憶體,雖然說RAM可以買賣,但依然存在很多人炒作,導致RAM價格昂貴。
開發難度大:使用C++作為合約開發語言,極大的提高了合約開發門檻,C++本身就極為複雜,在其上還要去呼叫EOS.IO C++ API完成智慧合約開發,對開發者的個人能力要求極高。

因此面對種種可列舉的問題,EOS智慧合約開發對於開發者吸引力不大,甚至會成為開發者放棄EOS的理由。

四、IOST虛擬機器的誕生

我們認為一個良好的虛擬機器實現必須在做到架構設計優雅的同時滿足易用性和安全性的需求,在經過對比參考EVM、EOS、C Lua、V8等相關虛擬機器的優缺點之後,我們從根源上解決了很多EVM和EOS不合理性設計與問題,並且基於V8在NodeJs和Chrome上的優異表現,最終構建了基於V8的IOST虛擬機器。

01 IOST V8VM架構與設計

VMManager系統構架

V8VM架構的核心是VMManger,主要有如下三個功能:

VM入口,對外接收其他模組的請求,包括RPC請求、Block驗證、Tx驗證等等,預處理、格式化後交給VMWorker執行。
管理VMWorker生命週期,根據當前系統負載靈活設定worker數量,實現worker複用;同時在worker內部實現了JavaScript程式碼熱啟動、熱點Sandbox快照持久化功能,減少了頻繁建立虛擬機器、頻繁載入相同程式碼引發的高負載、記憶體飆升問題,降低系統消耗的同時,又極大的提高了系統吞吐量,使得IOST V8VM在處理fomo3D這種典型的海量使用者合約時遊刃有餘。
管理與State資料庫的互動,保證每一筆IOST交易的原子性,在合約執行出錯,或者gas不足的情況下,能夠回退整個交易。同時在State資料庫中,也是實現了兩級記憶體快取,最終才會flush到RocksDB中。

02 Sandbox核心設計

IOST Sandbox系統構架圖

Sandbox作為最終執行JavaScript智慧合約的載體,對上承接V8VM,對下封裝Chrome V8完成呼叫,主要分為Compile階段和Execute階段:

Compile階段

主要面向合約開發和上鍊,有如下兩個主要功能:

Contract Pack,打包智慧合約,基於webpack實現,會打包當前合約專案下的所有JavaScript程式碼,並自動完成依賴安裝,使IOST V8VM開發大型合約專案變成可能。同時IOST V8VM和Node.js的模組系統完全相容,可以無縫使用require、module.exports和exports等方法,賦予合約開發者原生JavaScript開發體驗。
Contract Snapshot, 藉助v8的snapshot快照技術,完成對JavaScript程式碼的編譯,編譯後的程式碼提升了Chrome V8建立isolate和contexts的效率,真正執行時只需要反序列化快照就可以完成執行, 極大的提高了JavaScript的載入速度和執行速度。

Execute階段

主要面向鏈上合約真正執行,有如下兩個主要功能:

LoadVM,完成VM初始化,包括生成Chrome V8物件、 設定系統執行引數、匯入相關JavaScript類庫等等,完成智慧合約執行之前的所有準備工作。部分JavaScript類庫如下:

Execute,最終執行JavaScript智慧合約,IOST V8VM會開闢單獨的執行緒執行合約,並監控當前執行狀態,當發生異常、使用資源超過限制、執行時間超過最大限制時,會呼叫Terminate結束當前合約執行,返回異常結果。

03 IOST V8VM效能表現

我們認為作為公鏈最核心的底層設施,虛擬機器必須在效能上表現足夠優異。IOST在設計、虛擬機器選型之初,就把效能作為最重要的指標之一。

Chrome V8使用JIT、內聯快取、惰性載入等方式實現JavaScript的解釋執行,得益於Chrome V8的高效能,IOST V8VM的JavaScript執行速度有了質的提升。我們在遞迴fibonacci、記憶體拷貝、複雜cpu運算這三個方面,分別測試了EVM、EOS、C Lua和V8VM的效能,具體結果如下:

測試系統環境

測試結果

實測IOST V8VM在主流VM實現中,效能表現優異。上述測試包含了虛擬機器啟動和載入配置的時間,可見IOST V8VM直接冷啟動也有不少的效能優勢,後續我們還會加入VM物件池、LRU快取等等,來提升虛擬機器CPU、記憶體使用率,以更好提升IOST處理智慧合約的能力。

04 結語

目前我們已經完成了IOST V8VM虛擬機器第一版的開發,在第一版中,我們已經實現了所有預定的功能,在後續的迭代過程中,我們將把IOST V8VM的安全性、易用性放在首位,並在如下三個方向不斷努力:

高效能,保證合約更快的執行
開發上手更加簡單,增加並完善更多標準庫
支援大型專案構建,除錯,有完善的工具鏈

同時在第一版IOST V8VM的開發中我們初步驗證了很多想法,例如投票、合約域名、token等等,更多的新功能、更多的新特性都會在接下來的測試網更新中逐步實現。

附錄: 虛擬機器benchmark程式

01 evm code

02 Lua Code

03 EOS Code

04 V8 code