當前位置:
首頁 > 最新 > 一文看懂區塊鏈虛擬機

一文看懂區塊鏈虛擬機

沉迷學習,無法自拔。

文 | 盧曉明

編者按:區塊鏈涉及到的技術很多,從互聯網底層到不明覺厲的密碼學,可是往往關注幣價者多而研究技術的人少。牛市的時候,大家為了炒幣也會努力學習,熊市的時候,反正也沒啥事,我覺得可以更加努力學習。作為一個文科生,我當然會有很多理科生看起來覺得很白痴的問題。作為一個記者,我不難找到業內懂的人用人話給我解釋,而且他們往往不會當面嫌棄我。

我寫下我的學習筆記大家分享。這次學習的是虛擬機,還準備學習的有跨鏈、VRF、開源歷史和文化、網路體系結構與區塊鏈分層體系對比、「假如把幣圈看成一個國家這個國家的貨幣在經歷什麼」。如果有其他有趣問題,歡迎投稿和提問。

這篇筆記真的長得超出我意料之外

智能合約是目前公鏈需要完善的一大方向。

以太坊的智能合約多次出現漏洞,業界普遍認為與智能合約太過靈活有關,即以太坊想把智能合約做成圖靈完備。此前在我採訪 ArcBlock CEO 冒志鴻的時候,他總結,以太坊智能合約漏洞,一是因為太過靈活了;二是由於虛擬機和語言是新做的,不太成熟。「前段時間發出溢出的問題(美圖幣的問題,都是整數溢出導致的),本來應該在語言層面就解決 。」

基於以太坊存在的這兩個問題,致力於「做更好的以太坊」或者「垂直版的以太坊」的項目,會在原來的基礎上改進,或發明自身的智能合約語言,我報道過的有以分片落地為特色的公鏈 Zilliqa,還有電商公鏈 CyberMiles。

CyberMiles 的虛擬機(CVM)及高級編程語言 Lity 是在最近發布的,我藉此機會向他們首席科學家 Michael Yuan 請教了一些關於虛擬機的基礎知識,並將我們的對話整理了出來。

記憶中,我最初接觸到虛擬機是在學校網路中心做網管(此處省略一萬字關於文科生在網路中心被碾壓的悲慘故事),因為許可權比較高,會在學校數據中心有個虛擬機上的賬號;後來是我在財新實習時,一位同事為了在 Mac 系統上裝萬得而裝了一個 Win 虛擬機;然後是在我報道阿里雲和 Docker 合作時,由於虛擬機與 Docker 都是虛擬化技術,當時了解了一下兩者的區別;最後,我又聽到了 Java 虛擬機和以太坊的虛擬機(EVM)。

至此,我聽過了操作系統之下和之上的虛擬機,究竟什麼是虛擬機,先有系統還是先有虛擬機,為什麼區塊鏈需要虛擬機?

什麼是虛擬機?

虛擬機顧名思義是相對於物理機而言,比如你們明明在用同一台電腦,我讓你們覺得自己分別有一台電腦;你明明在用很多台電腦,讓你覺得自己在用一台電腦。定義這種東西當然問度娘很容易找到,當往往似懂非懂——虛擬指通過軟體模擬的具有完整硬體系統功能的、運行在一個完全環境中的完整計算機系統。但是操作系統之上的虛擬機似乎就不是那麼回事了。

Michael 說人話的解釋加深了我對虛擬機的理解。他告訴我,虛擬機的出現比 Windows這類操作系統和互聯網還早,最早是為了解決計算機的分時租賃問題。

小明:虛擬機的作用究竟是什麼?最早什麼時候出現?

Michael:「最開始大型計算機是很多用戶共用的,就是你用十秒,我用十秒,你覺得這台機器一直都是你的,我覺得它一直都是我的,但我其實不停地在等它十秒。在計算機從你切換到我的時候,必須重新把你剛剛計算的那些東西,全部給 restore 回來給你看,然後十秒鐘之後,把你的去掉,把我的東西全部露出來給我看。」

「我們用的是同一台硬體,但上面有不同的虛擬機,每個人覺得這個硬體是自己的,但其實是用軟體方法實現的,就是在大型機上實現虛擬機的做法。後來個人虛擬機的作用就小了,就沒有必要去用。直到 1997 年 Java 出現的時候,虛擬機又變的特別重要。因為那個時候有Windows、Unix各種各樣的操作系統。Java 是第一個說我用虛擬機把這些全部統一起來,你們就不用專門在 Windows寫一個,在Unix寫一個了,你們就用 Java 寫,我上面有虛擬機。」

「虛擬機就是一個抽象化的作用,我虛擬機有自己的語言,然後你可以在虛擬機裡面寫東西,但是虛擬機下面可以有不同的硬體、不同的軟體,甚至同一個硬體我怎麼分成不同的時間片。虛擬機為什麼叫做虛擬機?就是他把下面的東西給抽象掉了,你不需要管你的下面是什麼。」

最早的虛擬機大概是 1965 年前後,IBM 的發明:一個單一的計算機系統可以通過 IBM 模型來模擬多個裝有不同操作系統的計算機。這使得用戶可以在一個計算機上創建和管理多個不同的虛擬機拷貝。IBM 模型的一個主要特徵就是通過分割計算機資源和完全隔離程序來使程序共享同樣的硬體。(copy 自《虛擬機總結》)

到上世紀 90 年代時,Java 程序語言開始流行,這打開了虛擬機應用的重頭戲。因為當時網路跨越了不同的操作系統,不同的瀏覽器,不同的設備,要想運行同一個應用程序是何等困難,Java 正好滿足這種需求(Java 虛擬機的最主要特徵就是程序只要書寫一次就可依託 JAVA 虛擬機在多個平台上執行),就順應時代需要流行起來了,當時宣傳的口號是 「一處編譯,到處運行」。(copy 自《虛擬機歷史》)

到 2005 年,Google 就收購 Dndroid 這個系統,2007 年發布第一個開源版本,在這個系統里存在一個叫 dalvik 的虛擬機,它跟 Java 虛擬機有點像,但它又是不一樣的,因為它主要被設計運行在手機和平板電腦里,內存有限、 CPU 頻率低的機器里,目前已經數不勝數的手機應用運行在這個虛擬機里了。隨便 Android 系統的攻城拔寨,可以這樣說:前 30 年的 IT 業可以用 Intel Inside 總結,後 30 年就可以用 Android Inside 來形容了。這個當初被 SUN 設計運行在嵌入式設備里的虛擬機,直到今天的 dalvik 虛擬機才真正地實現它的原本應有輝煌應用,才做到所有設備統一平台的機會。(copy 自《虛擬機的歷史》)

為什麼區塊鏈需要虛擬機?

理解了虛擬機「統一」的作用之後,原來的認知告訴我,虛擬機的性能肯定比不過你直接調用物理機,當中會有些損耗,按理來說層級越多損耗越大。為什麼區塊鏈為什麼需要給自己增加一層虛擬機,它需要統一什麼?

簡單來說就是:區塊鏈有共識機制,所以要求所有人的計算結果是一樣的,但是傳統的虛擬機不支持這樣,後者可能會因為底層硬體的不同輸出不同的結果,所以 V 神要再寫一個。之前採訪老冒他也說過,「以太坊之所以選擇寫一套新語言Solidity,就是為了能實現智能合約代碼的一致性。」

小明:區塊鏈上的跟我們傳統接觸的虛擬機有什麼不同?為什麼需要虛擬機?

Michael:Mainframe 大型機的虛擬機是在操作系統下面的,Java 虛擬機在操作系統上面,所以就是不同的虛擬機。區塊鏈的虛擬機到底統一了什麼?區塊鏈的虛擬機統一了不同的節點,每個節點都是不一樣的。

底層語言用比如C++構起來,虛擬機要麼就是 Vyper 或 Solidity ,要麼就是虛擬機有自己的語言。第一代區塊鏈是沒有虛擬機的,比特幣是沒有虛擬機的。比特幣就是交易,把錢從A打到B,但是以太坊的天才想法是,我為什麼交易一定是要把錢從A打到B呢?為什麼我不能讓 A 到 B 這個過程是一段代碼?但是要執行這段代碼,需要在上面有一個執行代碼的層面,這個層面就是虛擬機。

這時候,區塊鏈的作用也從打錢不會出錯變成執行代碼不會出錯,這需要所有的節點執行同一代碼都是同樣的結果。

所有的節點在這個執行的代碼上有同樣的結果,這個要求很高。因為在傳統的虛擬機,比如Java虛擬機裡面,是達不到這一點的。因為有些機器是64位的,有些機器是32位的,10 的負十次方,在 A 機上表示和B機上表示是不一樣的,這樣計算的話,各個節點不容易發生共識,所以他必須要寫自己的虛擬機。因此,Vitalik就寫了第一版以太的虛擬機。

這虛擬機還得防攻擊,因為虛擬機裡面不能說任意代碼都可以執行,否則會有人來寫無限循環執行的代碼。因此,虛擬機裡面要做 gas,要知道這個東西存儲量有多大(智能合約的代碼存在區塊鏈上,代碼越長 gas 費會越高),根據這個我幫你收錢,要通過交易費來保證虛擬機上的安全。所以區塊鏈的虛擬機跟通用計算的虛擬機的需求是不一樣的,但是作用其實是差不多的,就是要執行一段代碼。

小明:那以太坊虛擬機改變什麼?它做到了這個有什麼壞處嗎?

Michael:他犧牲了性能,Java 虛擬機性能後來大幅提高,是因為所謂 Just-in-time (JIT,即時編譯),虛擬機會根據現在的這段代碼來預測下一段代碼是什麼。Java虛擬機是非常非常聰明的,因為在裡面花了大量的錢,搞了大量的優化。以太坊虛擬機首先從來沒有干過這個事,因為在 2016 年以前沒有人花任何錢去干這事,大家都認為這是個小孩做的事情,這是其一。

其二,優化過程也很複雜, Java 虛擬機裡面可以容忍不同的虛擬機裡面出來的結果有少量的差別,這個是可以的。但是在區塊鏈里不行,區塊鏈里所有的結果都必須一樣。

今天在區塊鏈虛擬機,其實也就三個流派。一個是從以太坊改的;然後 EOS 是從 WebAssembly 改的,是一個 JavaScript 虛擬機,在 EOS 之前就有了,他把裡面跟區塊鏈不符合的東西去掉;現在又看到一些去改 Lua 的虛擬機,Lua 是一種經常在 IoT 中使用的腳本語言。

我覺得也沒有任何理由,需要去重新解決虛擬機。因為 Vitalik 寫過一個虛擬機,19歲的時候就寫了,這也不是什麼特別難的事。

為什麼有的鏈需要發明一套新語言?

正如我開篇所言,有的項目會開發新的虛擬機,往往也會伴隨著新的虛擬機語言。這說的是什麼意思?

離題一會,講一下虛擬機、虛擬機語言(高級語言)和編譯器的關係。

簡單來說,虛擬機決定虛擬機語言,編譯器是寫這個語言的工具。

虛擬機是你所寫代碼的運行環境,就像「一個世界」。維特根斯坦說過:「語言的邊界是就是世界的邊界。」語言就像這個世界能做的事情的外化,語言中有哪些辭彙,說明這個世界能做什麼,一旦你寫了超過這個世界能理解的詞,虛擬機是不會執行的。這兩個東東某種程度是一體的,一旦你的虛擬機支持了新功能,也需要有相應的辭彙來將其外化。

至於編譯器的常見作用,有點像把人能看懂的語言,翻譯成計算機能懂的語言。

不過,這兩種都是直接面對硬體/處理器的,都跟處理器種類有綁定。高級語言則不然,比如Java、C、C++、C#、python等等,是高度封裝的編程語言,更易學也意味著更不靈活。用其所編寫的軟體源代碼也能被編譯器翻譯為不同處理器的語言。

可見,「低級語言」可能更「高級」,因為靈活(越低級的語言實現的效果越強大),更難掌握,懂的人也更少。

回到正題,要開發新語言,其實就是要做新的虛擬機,做以太坊虛擬機沒做的事。

CyberMiles 主要是針對垂直場景做優化。CyberMiles 的虛擬機(CVM)是基於以太坊的虛擬機改的,所以兼容以太坊虛擬機語言 Solidity,同時支持一些以太坊虛擬機所不支持的功能。這意味著如果你本來就懂 Solidity,你可以用 Solidity 寫,但是如果你想用到 CVM 的一些功能,這部分你就可以用 Lity 寫,CVM 兩者都能「看得懂」。

Michael :Lity 和 CVM,對於CyberMiles 最重要的一點就是,讓我們做以太坊不能做的事。其實我們是以太坊社區裡面的。我們不認為我們跟以太坊是一種競爭關係,我們跟他們是不同的哲學。他們在追求另外一個目標,他們在追求世界計算機的目標,我們不是。我們承認90%的事我們幹不了,我們就把10%的事幹了,所以我們 Lity 和 CVM,是把以太坊的一個圖靈完備的系統,針對特定場景優化。

Vitalik 2015年的時候就知道了我們的做法,但是他不願意做,因為他不願意把以太做成一個為電商或者為跨鏈優化的一個虛擬機,他希望能夠找到一個通用的解決方案。這就是一個世界觀的問題,以太坊講到的是世界計算機,我們不想當世界計算機,我們認為沒有人能當世界計算機,一個做得好的區塊鏈是垂直的。

這中間還需要去中心化交易。因為不可能我電商用一種幣,吃飯用的是一種幣,要能夠實時地高水平交換才行,今天已經在解決,比如Cosmos這樣的跨鏈項目。我們不想解決這個問題,我們還是想乾電商。

CyberMiles 基於 EVM 做了哪些優化?

那麼,CyberMiles 的虛擬機 CVM,跟 EVM 相比優化在哪?通過 CyberMiles 做的一些優化,也可以幫助我們理解以太坊的特性。

第一,可動態擴展,CyberMiles 所開發的語言可以針對不同的業務場景做優化,提高性能。

據 CyberMiles 官方介紹:「Lity的靈活性源自其添加新的語言OTA架構。這個版本中,LibENI函數是亮點。通過 CyberMiles 虛擬機中新的 OPCODE,使用者現在可以在 Lity 語言中添加更多功能。這種擴展可以在不停止或者升級區塊鏈軟體的情況下,通過超級節點共識,動態部署到 CyberMiles 區塊鏈上。」

給看不懂的官方介紹加點注釋(詳細可看最後參考文章):

OTA 是 Over the air,就是在虛擬機不重啟的情況下,動態地升級系統本身的軟體。手機的無線升級系統也用到的類似的技術。

OPCODE 即operation code,操作碼,是一堆機器語言的指令集,簡單來說就是指令序列號,用來告訴CPU需要執行哪一條指令。CVM 在 EVM 里加了後者沒有的 OPCODE 以實現自己的功能。

Michael :在一邊運營的情況下,我可以一邊往裡加些新的功能和特性,這是很重要的一點。比如我有個新的加密演算法,在以太坊的實現非常非常貴,我就用 C++ 能夠把它加進去,在我機器不下檔的情況下,我可以往裡面加東西。

作為電商公鏈,我們開發出來的虛擬機,或者我們開發出來的語言是能擴展的。其他人要做一個外賣公鏈或金融公鏈,完全可以用,這也是我們做開源共享的原因。

第二,在 Lity 編譯器和 CVM 上安裝代碼檢查模式。簡單來說,對已知的以太坊Solidity智能合約引起的安全問題,CyberMiles 團隊進行了分類並提取了常見模式。通過編譯器和虛擬機優化,Lity 可以主動防止 Solidity 中常見的安全問題,如整數溢出和通證被意外轉到不受支持的合約地址。

Michael :我們有一個building feature,比如剛剛講了 BEC 的安全漏洞,就是忘了加safemath,所以就會有整數溢出的問題,後來掉了幾億美金。BEC 的合約可以在 CyberMiles compile,可以在我們虛擬機上運行。但用同樣的問題不會發生在我們虛擬機上,因為我們虛擬機在 runtime 的時候會查整數是不是被溢出,會報錯。我覺得這個就顯示了 EVM 的成熟。這種東西在 Java 裡面都出現過,1997年 Java 開始,Java 裡面也沒有 check,後來就加進去。

第三,基於時鐘的長期智能合約。Lity就可以執行一些發生在未來的事情

Michael :以太裡面還有一個大問題:以太的合約是不能自己啟動的。你不能設計一個鬧鐘讓合約在未來某天啟動。但在電商裡面經常有這事,比如匯款和發貨。在以太幹不了這件事,在以太坊專門有一個東西叫以太坊鬧鐘,這是一個線下的機構,專門收錢,幫你到了某個時間,來實施以太坊的合約。我們把它做進虛擬機了。

這個東西聽起來是很小的事。你去看Java的發展歷史,這些事情都發生過,就是因為你在企業應用中,要是沒有這個功能,你做不到分期付款。

比如說今天Solidity是不能小數運算的,只能是整數,為什麼?因為在不同的機器上,小數運算產生的結果不一樣,所以沒辦法達成共識。那我們在這裡就改變了這一點,數學運算的庫就大多了。你要搞錢的事,小數運算還是需要的。我覺得當然還有其他的特徵,比如白皮書里提到的規則引擎。

規則引擎是什麼?規則引擎就是有很多嵌套的條件邏輯,在你的程序裡面都不用去手寫,用手寫的話錯誤率就很高。這就是為什麼在企業級用戶裡面,大家都用規則引擎,不會自己去手寫那種很長的規則,這種很長的 rules,他們改不了。但我們就把 rules 放在虛擬機裡面,所以你可以直接寫一套規則出來,在虛擬機裡面執行,而不是還需要低層次的東西。

這些「優化」有什麼代價?

跟 Michael 聊完,其實會發現,很多 CVM 針對垂直行業的優化,以太坊真的是「非不能也,是不為也」。如果一條通用計算公鏈,要實現這些功能可能會犧牲一些東西,最直接的就是治理機制。CVM 之所以能實現高性能,需要一定程度上與底層操作系統做溝通,但是以太坊不可能要求加入網路的節點都用特定的系統,可是用 DPOS 的 CyberMiles 可以;虛擬機層面實現的模塊化、可擴展,也需要基於 DPOS 超級節點全體同意

換言之,CyberMiles 的語言跟跟他採用 DPOS 的共識機制分不開,這是以太坊不願意採用的。

關於虛擬機的性能優化

小明:我們這次的幾個特性,LibENI函數,還有剛剛提到的代碼檢查,我感覺這個好像主要是在虛擬機本身上面,因為語言本身無法決定我是否被檢查?

Michael :語言包括語言的語法和它的編譯器,檢查的東西放在編譯器裡面,這個是語言系統的一部分。但是 LibENI 必須要在語言領域實現。因為在以太坊領域有一個概念,是沒有一個可以添加的函數,以太坊在白皮書都寫清楚了。那我要在裡面新加OPSCODE,這個是對語言本身的一個改變。還有就像鬧鐘這種東西,鬧鐘這東西也需要在語言上掌握關鍵詞,才可以說我要三天後執行,十天後執行。

小明:那回到我一開始最初問的問題,我感覺虛擬機所在的層級越高,損耗其實越大。

Michael:對,這就是為什麼以太坊虛擬機效率低的一個原因,它是在OS之上的。以太坊的客戶端有兩個,一個是Geth,一個是 Parity。你要 run 一個以太坊的許可權,你要麼run Geth,要麼 run Parity,下載很大的一個數據包下來。新的 Transaction 進來後要出塊後,你計算機的以太坊虛擬機,也要全部進行一遍,要跟其他網路上的東西對得上你才能夠繼續往下走,不然你就不在這個網路上了。

小明:所以我們虛擬機也是一樣的?

Michael Yuan 博士:一樣的,但是我們的虛擬機有加密演算法 LibENI。為什麼叫LibENI?ENI就是說以太坊本地介面,它往底下的操作系統,是我們用 C++語言打出的一條路來,這就是以太坊不願意乾的,以太坊東西全部是自洽的,全部都是在操作系統以上的,全部是數學可以證明的東西。我們在上面弄了一個 C++的口,所以說我們要算加密解密,我們就通過那個口,給撞到操作系統的層面之下,那當然性能比它快多了。

小明:這樣如果我們底層操作系統不一樣,或者低層的硬體也不一樣,不會導致你剛剛說的不一致嗎?

Michael :對,所以這就是 LibENI 裡面的內部機制,所以LibENI出模塊的時候,需要出好幾個系統模塊。比如說 Ubuntu Linux,windows什麼的都有。但我們有一個好處,因為我們超級節點是可控的,我們有些數量的超級節點,我們可以要求超級節點必須用這些操作系統。

小明:可以總結一下 LibENI 嗎?

Michael :它包括兩塊。一塊是Lity 層面,在虛擬機語言裡面看見的是什麼東西,這個需要定義一下。如果這個東西來了之後,在C++層面需要引進這東西,就是兩塊。然後讓超級節點同意。這個過程中,超級節點會看是否支持自身操作系統,否則做不了。

小明:所以我們有些東西很快,是 LibENI 決定的?

Michael :就是LibENI往裡加東西。寫 DApp 是用 Lity 寫,在虛擬機 CVM run。可是你要改虛擬機就是另外一個東西叫 LibENI。LibENI 是 Lity 的擴展,這種是用 C++語言。他等於改造虛擬機本身,虛擬機是用C++寫的,就等於把 C++封裝成一個模塊架上去。

小明:既然這是一個調用底層 C++ 語言的介面,為什麼那個函數不能讓所有的東西都調用它呢?

Michael :你是說把整個虛擬機都改裝成這樣模塊化是吧?不是所有功能都能用函數,虛擬機裡面有規則還有其他結構。如果能夠用函數解決問題,我們就能解決。什麼是函數呢?有輸入和輸出的東西。比如說一個私鑰和一個文本,就出來一個加密的文本。

小明:能舉一個普通人能感知到的例子?不能通過函數完成的。

Michael :比如說剛講的 rules,就是跟 control 有關的東西,比如從一到十的循環。剛講的規則引擎其實就是,這件事幹完,干這件事。這裡面的每一個要乾的事情都是一個函數,但整體結構不是一個函數。

小明:所以函數很多時候是單一的東西。

Michael :單一的東西,就是給個輸入,給個輸出。

語言的可擴展性與治理機制之間的關係

小明:CyberMiles 強調是面向電商場景定製的,但又強調擴展性比較強,我有一點不是很理解這裡。

Michael:因為可擴展性比較強,所以 CyberMiles 的鏈使用跟 CVM 裡面加的功能全是跟電商有關的。但是,我可以用LibENI 跟 CVM 造另外一個公鏈出來,那個公鏈可以是外賣的、打車的,或者是發證券代幣的。在技術上我們提供這個,可以按照你自己的需求去擴展CVM。

這種是超過了 CyberMiles 的範圍,因為 CyberMiles 想運營一個電商的公鏈和一個生態。可是,我們開發的軟體,比這個更通用,這就是我剛剛講的,我們非常希望大家來抄我們的東西,如果有一天大家不抄你的代碼,大家來抄我的代碼,我覺得這就是我們成功的標誌。

小明:你提到我們的語言擴展性強,那什麼樣的語言擴展性不強呢?或者定義一個語言強或不強的標準是什麼?

Michael :EVM和Solidity就是沒有擴展性的,就是你不能改,你需要改的話,你是要把整個軟體系統都更新。EVM軟體大概一年要更新一次。你在EVM上更改東西的話,你基本上必須要自己認識Vitalik,所有的核心開發他都會參與。

我們把虛擬機這個東西變成一個大家都可以改的東西。比如,我們就在 Solidity 開了個口,我可以讓你直接把 C++ 的口給放進來,所以這個東西用 C++來做,只是在以太虛擬機上沒辦法而已。在PoW上實現不了,因為你需要在不更新軟體的情況下去更新軟體上的一個虛擬機,這就是軟體裡面的一個核心成分,這個需要全網所有節點的共識。在以太上需要所有礦工要共識這一點是非常難的,但我們做DPoS,所以我們用超級節點共識做這件事就可以了。

小明:這是你剛剛提到的,我們有很多功能可以讓開發者自己提,讓節點去接受。

Michael:我們提供了一個方法,能夠用封裝好的工具感知你的痛點,我們虛擬機裡面加工的,比如我虛擬機裡面以前可以做 RSA 演算法的加密,我現在想做 DES 演算法的加密,那就是另外一個功能。你可以把它打成包,讓它們超級節點來同意,同意了之後就加密去了。飛機一邊飛,一邊換引擎。

小明:所以其實我們擴展性強,並不是由語言決定,而是由我們治理機制決定的?

Michael :我們語言跟虛擬機和治理機制是一起工作的,不可分割的。因為我們這個語言裡面可以去加這種關鍵詞,我有個模塊化的方法,可以把這個關鍵詞的功能直接加到虛擬機里來,這在現在來講以太坊都做不到,因為不支持。

關於虛擬機的靈活與安全之爭

小明:很多人批評現在以太坊智能合約本身有很多漏洞,包括整數溢出這些,都是因為虛擬機本身設計可能沒有做好?

Michael :我覺得是這樣,寫虛擬機或者寫語言的人,會說是寫智能合約的人的問題,你們程序員太差,所以有這個問題。如果所有人都犯一樣的錯誤,那就說明你這個東西設計的不行,所以你就要想辦法去改設計。之前我們在Java的時候,也遇到這種問題。這個Bug出現是不是因為程序員的問題呢?是因為程序員的問題,也是因為你的語言沒有防止這個問題,所以一直以為有這個問題。

這就是工程解法跟科學解法的區別,或者叫學院派思維跟工程思維的區別。

我以前在大學很清楚,學院派思維會說,我們設計出來東西是圖靈完備的、數學可以證明的。比如說整數溢出這件事,你憑什麼說它是個bug?因為我的語言裡面允許這樣寫。程序員把它寫成這樣,就是證明他想干這個事。但是,在現實生活中,99.99%的情況下,程序員不是要干這件事,而是把它寫錯了。

我們就幹了一件 Java 以前乾的事情。就是整數溢出了之後,我們不能執行下去了,我們虛擬機就報錯了。

小明:以前 Java 的虛擬機是允許這個事情的?

Michael :所有虛擬機都經過這個爭論:這東西到底是bug還是個feature?我們允許大家這麼干。

小明:靈活的「壞處」。既然虛擬機又是在操作系統之上的,那就意味著操作過程中,其實操作系統可能也有虛擬機,下層不能知道發生這件事嗎?不能阻止嗎?

Michael :底層的虛擬機你願不願意干這事?越底層的虛擬機就越有可能想干這個事。在你看來是整數溢出的東西,也許在下面並不是整數溢出。所以你越往下走,你就越需要給人自由。所以越底層的軟體,對程序員的要求越高。你比如說你要用機器語言寫東西是非常非常容易出錯,但是你有最大的靈活性,你有最大的優化能力,整個系統所有的資源你都可以用。但是你要到了Java這一層,或者EVM這一層,你系統很多東西根本看不見了。內存在哪裡你根本就不知道,因為它都會抽象化。

小明:那假設下層的虛擬機不允許某種行為,但上層的虛擬機允許,那他又寫了,下層會阻止嗎?

Michael :在某些情況下會阻止,這個就是如果不同的情況,就比如我們剛才講的,你在CVM里整數溢出了,在操作系統裡面看不一定是整數溢出。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Odaily星球日報 的精彩文章:

跨境支付切入進出口貿易市場,「捷匯科技」主打中小商戶

TAG:Odaily星球日報 |