EOS-VM是EOS.IO成為通用區塊鏈協議的重要基石,同時超越了EOS.IO自身,將會成為事實上的區塊鏈虛擬機技術標準,甚至會將以太坊和波卡尚在起步階段的虛擬機開發扼殺在襁褓中。
0、前言
EOS.IO開發團隊 Block.One于2019年6月1日發布了全新的EOS-VM。
EOS原力團隊在經過大規模測試后認為,EOS-VM 將成為區塊鏈行業使用率最高的 VM,也將率先成為區塊鏈行業 VM 的事實標準。
我們在《EOS.IO 將迎來史上最復雜硬分叉升級》一文中曾經講過,多個重要的分支都在積極開發中,而 EOS-VM 就是一個重要性不亞于 1.8.0 的分支。該分支從 2018 年 7 月份就開始了,從提交記錄上來看,早期的 EOS-VM 并沒有特別緊湊的開發計劃。然而從 2019 年開始,經過了一系列密集的開發,初步完成了今天我們所看到的 EOS-VM 項目。
如果說 EOSIO1.8.0 版本讓我們看到了 Block.one 在 EOS.IO 上的決心,那么 EOS-VM 可以讓我們一窺 Block.one 在區塊鏈行業的野心。
1、什么是VM
VM全稱為Virtual Machine,在區塊鏈語境下可以理解為智能合約的運行環境。
我們可以將智能合約類比于互聯網中的 HTML,區塊鏈系統可以看作操作系統,那么 VM 則是瀏覽器,各種基于智能合約的 DAPP 就是互聯網中的各種網站。
以太坊完成了區塊鏈系統中首個系統的智能合約支持,其 EVM 虛擬機也是早期智能合約開發者的主流開發環境,同時有非常多的項目都借鑒了以太坊的 VM,如 TRX 的 TVM。
但是 EVM 有其局限性,虛擬機效率相對成熟的虛擬機系統來說極其低下,難以支持更加復雜的應用和環境。
成熟的虛擬機系統是一個由一系列龐大的項目構成的體系,事實上,在目前的環境下,從零開始實現一個完整成熟的虛擬機系統是非常困難的,同時也是沒有必要的,因為對于這樣一個龐大的工程項目,從零開始意味著開發者和社區要承受大量的兼容和學習成本,最好的方式是基于現有成熟的虛擬機標準來開發適用于區塊鏈項目的虛擬機實現。
因此,大多數區塊鏈項目都選擇使用現有成熟的虛擬機實現,目前可以說最適合的莫過于 WebAssembly 虛擬機,除了 EOS.IO 之外,polkadot 也選擇基于 WebAssembly,而以太坊也在開發基于 WebAssembly 的 ewasm 項目。
對于區塊鏈領域來說 , 無論是不是「The Lesser Evil」,WebAssembly 已經成為非常重要的一部分了。
作為一個高性能的去中心化智能合約平臺,EOSIO 中所使用的虛擬機實現是整個項目中非常重要的一部分,在閱讀早期的 EOSIO 實現代碼時會發現,在調用虛擬機時,EOSIO 實現代碼中少有的做了很嚴格的封裝,以此來隱藏虛擬機實現的細節,可以見得 EOSIO 項目將會在虛擬機方面做持續重大的改進 。
// EOSIO chain 實現中少有的接口封裝
class wasm_interface {
public:
enum class vm_type {
wavm,
wabt
};
。..
private:
unique_ptr《struct wasm_interface_impl》 my;
。..
};
從最早使用的 wavm 虛擬機,到后面支持的 wabt 虛擬機,Block.one 團隊一直在改進虛擬機的支持,也在為多虛擬機兼容作準備,最終 EOSIO 發起了更高的挑戰,開發出了全新的 EOS-VM,最為 EOSIO 使用的虛擬機實現。
如果說 EVM 是一個區塊鏈虛擬機的話,那么 EOS-VM 則會是第一個可大規模商用的虛擬機。
2、EOS-VM 是什么
我們先來看看 EOS-VM 到底是什么,EOS-VM 是一個區塊鏈系統專用的 wasm 運行時。
在區塊鏈系統中,合約代碼會被編譯成字節碼的形式,這些字節碼不能直接在操作系統上運行,需要一個執行器來執行這些合約,在軟件體系中,可以把這些執行器視為一個抽象的「機器」,EOS-VM 就是這樣一個執行器。
EOS-VM 主要做四件事:
首先 ,EOS-VM 負責加載和解析編譯后的智能合約字節碼,也就是 wasm;
其次,EOS-VM 負責在字節碼運行過程中為其分配資源,當然對于智能合約來說,可用的資源就是內存;
再次,EOS-VM 負責向智能合約的字節碼提供虛擬機外的 API 調用功能;
最后,EOS-VM 負責執行字節碼來計算智能合約運行的結果。
在 EOS-VM 中 eosio::vm::backend 類是整個虛擬機系統調用的入口,在 tools 目錄下有兩個使用 EOS-VM 虛擬機的測試工具,想要詳細了解 EOS-VM 實現的讀者可以通過這些作為入口來閱讀 EOS-VM 的代碼。
int main(int argc,char**argv) {
。..
// 設置看門狗 , 限制運行時間為秒
watchdog《std::chrono::nanoseconds》 wd;
wd.set_duration(std::chrono::seconds(3));
try {
。..
// 加載 wasm 字節碼
auto code = backend_t::read_wasm( argv[1] );
// 創建執行環境
backend_t bkend( code );
wd.set_callback([&](){
bkend.get_context().exit();
});
。..
// 執行
bkend.execute_all(&wd);
} catch ( 。.. ) {
}
return 0;}
這里說的 EOS-VM 的主要工作,但如果只是這些的話,那其實和 wavm、wabt 沒什么區別了,在完成基本的必要工作之外,EOS-VM 針對區塊鏈應用場景做了一些重要的改進和優化,下面我們來結合 EOS-VM 的介紹文檔以及代碼實現來看看 EOS-VM 有哪些重要的改進。
3、EOS-VM 有哪些重要的改進
EOS-VM 針對區塊鏈應用場景作了很多的改進,這些改進對于智能合約開發者來說是最好的禮物。
下面我們先結合 EOS-VM README 文檔看看有哪些改進,再結合現有的 EOS-VM 代碼具體看一下 EOS-VM 是如果做到的。
在早期 EOS-VM 的 README 中 ,Block.one 列舉了以下的改進 :
1. Satisfying the needs of a blockchain.
2. Security built into the framework.
3. Performance centric design.
4. Light weight and easy to integrate solution.
5. Effortless extendability.
目前的 README 中改為了對于非開發者更加易懂的描述 :
· Extremely Fast Execution (6x faster than WABT)
· Extremely Fast Parsing/Loading (20x faster than WABT)
· Efficient Time Bound Execution
· Deterministic Execution (Soft Float & Hardware Floating Point options)
· Standards Compliant
· Designed for Parallel Execution
· C++ / Header Only
· Simple API for integrating Native Calls
我們來逐條分析 :
3.1 滿足區塊鏈場景下的需求
首先 Block.one 對 EOS-VM 的定位是「A VM for Blockchain」,這意味著 EOS-VM 中在 WebAssembly 的基礎上添加了很多區塊鏈所需的特定功能。
目前主要是三方面:
首先是浮點數的支持。對于浮點數,很多開發者往往片面的認為其運算是不精確的,無法用于區塊鏈系統。實際上并非如此,只是對于一些不同的硬件中,因為各種各樣的歷史原因,硬件中固化的浮點數運算有一些差異,解決這一點最好的方式是使用 softfloat 庫,不使用機器硬件提供的浮點數,這樣不同的硬件機器上,浮點數運算的結果都是相同的了。當然這里 Block.one 也提到,如果不在乎所有平臺上保持浮點數運算的確定性,則可以使用基于硬件的浮點數運算,這樣效率會比使用 softfloat 快很多,這種情況一般是節點硬件機器會保持統一的狀態下使用的。
在 EOSIO 中其實也集成了 softfloat 庫,但是之前的實現是在鏈中嵌入的,原生的虛擬機中本身不支持,現在并入虛擬機實現,可以降低其他區塊鏈使用 EOS-VM 時的開發成本。
其次是 EOS-VM 增加了 watchdog 機制以確保運行字節碼的運行時間限制,這個類似看門狗的機制,會在細粒度上對合約進行資源使用限制。
這一點很重要 , 以至于后期的介紹文檔中要單獨分出一節來描述。
如果看過 EOS 現在的代碼,會發現有很多大量雜亂的代碼在處理合約執行超時的問題,對于一個圖靈完備的智能合約來說,最大的困難在于我們如果不執行一遍其合約,就無法知道其執行消耗,所以 EOS 中需要邊執行智能合約邊判定其消耗時間,對于 EOS 鏈的環境來說 VM 是個黑盒,所以如果在 VM 外來進行合約執行時間判定的話就會非常困難,而 EOS-VM 在這方面提供了內置支持,相關的實現就會非常簡單,也會避免這方面出現的問題。
最后是一些虛擬機執行時的邊界限制,這些邊界限制乍看上去是一些功能的限制,但是在區塊鏈應用場景下,這些限制不會帶來實際功能的限制,反而基于這些斷言,EOS-VM 可以得到極大的優化。
3.2 內置的安全性支持
支持智能合約的區塊鏈系統可以視作一臺公用的計算機,而公用意味著必須對使用者進行限制。如果使用者可以毫無限制的運行自己的代碼,那么會帶來很大的安全性問題,對于公鏈來說,這是不能接受的。
這里的安全性問題主要是兩方面:代碼行為的安全性和代碼消耗的有界性。
首先,EOS-VM 通過內置類型來保證類型的安全性,并且通過可選的分配器來使用系統提供的機制來保證沙箱性。
另外,上文提到的 watchdog 機制以確保運行字節碼的運行時間限制。對于公鏈來說,如果沒有有效的機制,這一點往往會引起公鏈的安全問題。EOSIO 之前就出現過基于延遲交易引發的阻塞攻擊問題,這個問題本質上就是沒有有效細致的界定資源使用的問題。相應的以太坊也多次出現類似的問題,以太坊早期的數次硬分叉都是為了解決這類問題。
最后,EOS-VM 在任何時候都不會觸發無限制的遞歸或循環,嚴格限制某些 WASM 有意或者無意導致的崩潰或無限掛起機器的情況。
這些內置的安全性支持將會大大提高鏈的安全性,同時也會提供一個可控的安全性保證。
3.3 面向高性能的設計
在很多時候,特化就是最好的優化。
實際上,如果完全兼容 WebAssembly,那么 EOS-VM 優化的空間并不大。但是對于區塊鏈的需求場景,很多 WebAssembly 的設計并不需要,EOS-VM 基于這一點做了大量的特化,同時意味著性能上,EOS-VM 也得到了非常大幅度的優化。
EOS-VM 性能主要得益于對其內置化的類型的優化,EOS-VM 內置了絕大多數合約需要的數據類型,對于這些類型 EOS-VM 就可以對其一一優化,特別是 variant,這個類型其實并不是一個原生的功能。如果直接使用類似 union 的話,會造成很大的類型安全問題,使用 variant,雖然在實現時得到了很好的安全性和易用性保證。但是如果不將其集成入虛擬機層,那么其復雜的實現會帶來很大的性能損耗。
類似的還有 vector,如果閱讀現在的 EOS 系統合約,會發現大量使用了 vector,誠然對于合約設計來說,使用 vector 是非常便捷的,但是很多對性能特別敏感的開發者可能會對此感到非常「不安」,如今 VM 直接集成 vector,可以料想后續這些開發者就可以「更愉快的」使用 vector 了。
現在的 EOS 合約開發需要依賴一個規模不算小的基礎庫,這意味著每個使用這些基礎功能的合約都要集成其實現代碼,將大量的基礎庫代碼帶入 wasm 層,如今 EOS-VM 在虛擬機的實現層植入這些基礎類型,性能優化空間自然得到很大提高。
3.4 輕量級易于植入的架構
EOS-VM 是純頭文件的,這意味著 EOS-VM 可以被嵌入進幾乎所有的 C++項目中。
同時,EOS-VM 在設計做了特別的處理,使得 EOS-VM 可以很好的適應多線程環境,C++多線程編程一度是個「深坑」,構建一個可以在并發環境下安全運行的庫很多時候需要避免很多問題,EOS-VM 在這個問題上做了很多準備,可以避免重蹈像 std::string 在多線程環境下那樣的「覆轍」。
純頭文件的優勢還有很多,在這個方面 EOS-VM 已經很像在很多方面得到廣泛應用的 LUA,后者同樣以輕量級的運行時著稱,可以預見,未來會有更多的非 EOS 甚至非區塊鏈項目使用 EOS-VM。
3.5 高度可擴展性
EOS-VM 擁有一套精細設計的結構,從某些方面上來講,EOS-VM 要比 EOSIO 的代碼結構好得多。
EOS-VM 的設計中充分考慮了其拓展性,對于一個 VM 來說其主干結構幾乎沒有什么需要拓展和修改的地方,因為其功能就是上面提到的四件事。
但是對于不同的應用場景,其字節碼格式和功能必然需要拓展和修改,EOS-VM 在響應的地方都做了設計,其中深度應用了 visitor 模式,使得在不改變類架構的前提下也可以很容易的為整個 VM 添加功能。
在很多人眼里,一個良好的架構似乎沒有什么作用,畢竟你并不能把「架構良好」看作一個「前無古人」的新特性,但是對于項目開發而言,良好的架構會決定著整個項目后續的潛力。
總的來說,閱讀現在的 EOS-VM 項目,會有一種類似 lua 或者 redis 項目的感覺,整個項目規模不大,結構緊湊,代碼很干凈。
雖然大量使用 C++特性會讓一些初學者感到困惑,但并不會影響到對功能的理解,我們認為 EOS-VM 在未來將會在更廣泛的領域中發揮更大的作用。
4、EOS-VM 對 EOSIO 生態的影響
EOSIO 作為一個開源軟件,社區基于 EOSIO 啟動了不同功能和治理理念的 EOS 網絡、EOS、EOS 原力、ENU、Telos、worbli,BOS 等網絡均在 Block.one 的技術支持下發展,而本次 VM 的改革將使得所有基于 EOSIO 啟動的公有鏈受益。
從現有的實現來看,EOS-VM 將會盡量與當前 EOSIO 虛擬機實現保持兼容,出現不兼容的地方,也可以基于 abi 中的 version 來進行區別。未來即使出現大量和 EOS 原力一樣對 EOSIO 底層代碼進行了大量改進的區塊鏈,也可以輕松兼容。
未來一段時間之內,基于 EOSIO 鏈的公鏈的開發者可以集成 EOS-VM 到鏈中,同時保持原有 wasm 支持。
引入 EOS-VM 可以為鏈帶來很多好處和影響。
4.1 節約用戶資源消耗
如上文所述,使用 EOS-VM 可以提升鏈的性能,用戶使用基于 EOS-VM 運行的智能合約可以節省大量的鏈上資源消耗。
在基于 EOSIO 的公鏈中往往主要有三類資源:CPU、NET 和 RAM,CPU 主要由合約運行消耗的實際時間來結算,NET 主要與交易的大小相關,而 RAM 主要是基于合約帶來的狀態變換所使用的內存大小來決定的。
其中,現階段 EOS-VM 主要將會節省用戶 CPU 資源,這方面也是現在 EOSIO 網絡主要的資源限制,對于 EOSIO 網絡來說,NET 資源消耗往往固定,而 RAM 可以通過不斷的增發來激勵節點升級,這樣就可以在網絡上增加 RAM 的供給。
從硬件的角度來說,目前的服務器性能所支持的 RAM 升級空間還是非常寬裕的,但是對于 CPU,目前的限制很大,正如 BM 在電報群中所發的「牢騷」,英特爾并沒有給 EOS 造出 100 太赫茲的 CPU,當然這只是開的玩笑,但是確實當前服務器 CPU 性能限制還是比較大的,對于服務器來說,近幾年主要是并行計算能力的提高,單核性能雖然也得到了一定程度上的提升,但依然顯得不足。
為 EOSIO 添加并行計算支持是一個比較長的過程,即使 EOSIO 可以支持并行計算,也會受單核計算性能限制,因為對于合約來說,其計算過程依然是單線程的,提升虛擬機效率,對基于 EOSIO 的鏈來說非常有用。
4.2 使得鏈具有更強的拓展性
EOS-VM 無論是代碼還是架構都十分簡介明了,為了保持簡單和純頭文件化,Block.one 甚至沒有引入其「祖傳」的 fc 庫,多數開發者只要簡單了解一下 wasm 字節碼的定義文檔,就可以沒有障礙的閱讀和理解 EOS-VM 的設計和代碼。
這樣,開發者可以很簡單的在 EOS-VM 的基礎之上進行二次開發,尤其對于一些基于 EOSIO 技術的鏈,開發者可以簡單的添加新的類型以滿足特定鏈的特殊需求。
4.3 更簡單的開發外圍工具
EOS-VM 是純頭文件的,這意味著 EOS-VM 可以被嵌入進幾乎所有的 C++項目中,而且通過簡單的處理,EOS-VM 也可以被基于其他語言開發的項目中。
如 EOS-VM 中 tools 中的 interp,只需要不到 100 行代碼就可以構建起 EOS-VM 的運行時環境,這樣對于開發用于開發 EOSIO 合約的工具非常有用。
很多 EOS 合約開發的初學者都會想要調試合約代碼,在以往這是幾乎不可能的,雖然新版的 cdt 中也提供了一個 native lib,但是這樣也無法完美的模擬合約的運行環境。
雖然「好的代碼不是調出來的」,但是缺乏一個調試環境也會帶來一些麻煩。另一方面,我們也要考慮合約運行時與現有開發工具的集成問題,而 EOS-VM 可以很好的滿足這一點。
通過 EOS-VM,未來 EOSIO 開發生態將會更加完善,開發效率將會大幅提高。
5、EOSIO 正在向真正的協議演進
不知不覺中,EOSIO 的官網 slogan 已經從「最強大的去中心化應用平臺」改為「build on chang,build on EOSIO」。同樣在 EOS-VM 的設計中,開發者已經無法明顯感受到 EOSIO 和 DPOS 共識機制的存在,EOS-VM 的設計非常獨立。
如果一直關注 EOSIO 發展的話,會發現 EOSIO 的合約層在逐漸的去 EOSIO 化,從像 eosio_assert 改為 check 這樣的改名,到 cdt 中完全去除 capi 的調用這樣的重構,目前的 EOS 合約開發中,開發者會越來越少的碰到「EOS」。
一個典型的例子就是不同 EOSIO 姊妹鏈間的合約移植,現在基于 cdt 的合約在不同的項目間的差別已經越來越少,早期社區曾經對像 enu 這樣由于大量不必要的改名所引發的不兼容表示非常困擾,但現在如果使用 cdt 工具,開發者幾乎感受不到 enu 改名所帶來的不兼容。
這一切都在意味著 EOSIO 正在向真正的協議演進。
Block.one 團隊在早期并不像其他項目一樣,急于構建抽象的協議和形式化的黃皮書,而是以非常務實的態度進行 EOS 的開發,這也在一定方面上使得 EOSIO 這一公鏈的主網啟動要遠遠早于其他的「第三代」區塊鏈項目。
我們認為 Block.one 團隊不會一直在「埋頭造車」, 而是采用自底向上的思路,不斷的發展 EOSIO 生態,使其向真正的協議演進,最終成為一個極具競爭力的區塊鏈協議事實標準。
6、Block.one 打響區塊鏈標準之爭的第一槍
長久以來,任何一個軟件的細分領域都在謀求技術標準的整合和統一,這樣的統一并非是由中心話組織去強制推行,而是通過軟件本身逐漸得到主流市場的認可,最后成為事實上的技術標準。
而在區塊鏈 VM 領域,舊的虛擬機如 EVM 性能低下,單一功能的虛擬機無法承載復雜的智能合約,基于通用設計虛擬機將會成為未來主流區塊鏈項目的必需品,而這樣的區塊鏈項目目前唯一可選的只有 EOS-VM,EOS-VM 領跑行業一年多,將會成為最好的智能合約運行環境的標準,其行業地位將會類似于 ARM 在手機芯片行業的地位,甚至未來 ETH 的智能合約有望在 EOS-VM 上運行。
甚至我們也可以大膽的假設,EOS-VM 不會限于區塊鏈行業,由于其優異的設計和實現,甚至會被用于像游戲引擎、數據庫、Web 框架這樣的傳統軟件開發領域。
7、加密社區的開源與技術標準壟斷
我們都知道,Block.one 在向社區募資時一直強調自己是一個開源組織,所募集的錢也均要用于開發開源的 EOSIO 軟件回饋社區,也為加密經濟社區帶來了大量的貢獻。
但 EOS-VM 與 Block.one 以往任何一個開源項目都不同 ,Block.one 罕見地對 EOS-VM 項目保留了其權利 , 這意味著這個項目不會像其他開源庫一樣僅僅是一個開源庫。保留權利這一動作與其募資時純粹的開源組織定位產生了一定的偏差,甚至可能會通過商業性質的授權來限制其使用場景。
與傳統互聯網行業不同,加密經濟的大部分技術都是開源的,無論是擴容之爭和治理理念之爭均未涉及到技術標準層面,在開源的加密經濟市場中出現一個志在壟斷的 VM 將帶來什么樣的影響,我們拭目以待。
評論
查看更多