知道創宇區塊鏈安全實驗室 |一文讀懂 WebAssembly (WAS

買賣虛擬貨幣


前言

智慧合約開發語言已經被 solidity 統治了很長一段時間,用於開發可以在以太坊虛擬機器 evm 上執行的智慧合約。不過,solidity 有一些嚴重的問題,包括算術溢位、型別錯誤以及曾經凍結了 3 億美元的 delegatecall 漏洞。所有這些漏洞都是在開發語言層面存在的問題。換句話說,如果有一個更優越的開發語言,本應該創造出更安全的智慧合約。

因此, webassembly (wasm)智慧合約應運而生知道創宇區塊鏈安全實驗室從技術安全的角度,帶你快速探析備受歡迎的 webassembly (wasm)智慧合約 。


什麼是 webassembly (wasm)智慧合約?

webassembly (簡稱 wasm )是一種為棧式虛擬機器設計的二進位制指令集。wasm 被設計為可供類似 c/c++/rust 等高階語言的平臺編譯目標。最初設計目的是解決 javascript 的效能問題。wasm 是由 w3c 牽頭正在推進的 web 標準,並得到了谷歌、微軟和 mozilla 等瀏覽器廠商的支援。




wasm 具有執行高效、記憶體安全、無未定義行為和平臺獨立等特點,經過了編譯器和標準化團隊多年耕耘,目前已經有了成熟的社羣。在區塊鏈領域,包括本體在內,當前已經有一些公鏈專案正準備支援使用 wasm 來執行智慧合約。



webassembly 簡要來說有以下三個特點 :

  • 二進位制格式,不同於 javascript 程式碼的文字格式
  • 標準化,與 javascript 一樣,實現了 webassembly 標準的引擎都可以執行 webassembly,不管是在伺服器端還是瀏覽器端
  • 快速,webassembly 可以充分發揮硬體的能力,以後你甚至可以在 webassembly 中使用 simd 或直接與 gpu 互動


當前的以太坊虛擬機器按順序處理交易。以太坊網路上的每個節點執行交易並將其儲存在區塊鏈上。為了允許透過分片進行pos 和並行交易處理 , 以太坊團隊計劃構建一個名為 ewasm 的新虛擬機器。


根據 ewasm 的規範 :「要真正使以太坊作為世界計算機 , 我們需要有一個非常高效能的虛擬機器。當前的虛擬機器體系結構是原始效能的最大阻礙因素之一。webassembly 的目標是利用各種平臺上可用的通用硬體功能 , 以接近本機速度執行。這將為需要效能 / 吞吐量的各種用途開啟大門。」


值得注意的是,ewasm 不是一個智慧合約開發語言,而是一個編譯器的生成目標,它允許以太坊開發者使用其他語言(例如 rust、c++ 等)開發智慧合約並編譯為以太坊接受的 webassembly。


ewasm 是 webassembly 的一個安全子集,它是 web 平臺上相對新出現的編譯目標。方便的是,wasm (以及 ewasm )模組可以在任何 javascript 專案中使用。對於大多數 dapp 應用程式碼來說,通常 75% 以上的程式碼根本都不是智慧合約 —— 而是使用 javascript 與智慧合約進行通訊的程式碼。ewasm 和 javascript 使用同樣的繫結和模組支援機制。


為什麼選擇 rust 構建 webassembly?

隨著 2017 年底,四大瀏覽器廠商全部完成對 webassembly 的初步實現,以及 webpack implementing fifirst-class support for webassembly 的訊息公佈,越來越多的團隊在實現需求的時候將 webassembly 作為備選技術之一考慮。


rust 作為語言是一種高效、可靠的通用高階語言。其高效不僅限於開發效率,它的執行效率也是令人稱讚的,是一種少有的兼顧開發效率和執行效率的語言。rust 速度驚人且記憶體利用率極高。由於沒有執行時和垃圾回收,它能夠勝任對效能要求特別高的服務,可以在嵌入式裝置上執行,還能輕鬆和其他語言整合。


在探討 wasm 在智慧合約領域的巨大潛力時,前面提到 wasm 的一大優勢就是支援有影響力的新銳程式語言,例如 rust。使用rust 編寫 wasm 具有如下優勢:

可預見的效能

沒有難以預料的 gc 暫停,也沒有 jit 編譯器造成效能抖動,只有底層控制與上層人體工程學的完美結合。

更小的程式碼

程式碼尺寸越小,頁面載入速度就越快。rust 生成的 wasm 模組不含類似於垃圾回收器這樣的額外成本。高階最佳化和 tree shaking 最佳化可移除無用程式碼。

生態友好

充滿活力的庫生態系統助您旗開得勝。rust 擁有豐富的表達能力和零成本的抽象,以及助力您學習的友好社羣。


rust 編譯器目前支援兩個 wasm 關聯的目標 ( target ):

wasm32-unknown-unknown。此目標直接使用 llvm 後端編譯成 wasm。它適合純 rust 程式碼編譯,譬如你沒有 c 依賴的時候。跟 emscripten 目標比起來,它預設就生成更加洗練的程式碼, 而且也便於設定搭建。

wasm32-unknown-emscripten。此目標利用 emscripten 工具鏈編譯成 wasm。當你具有 c 依賴的時候就得使用它了,包括 libc。

wasm32-unknown-unknown十分有望將新生的 rust 程式碼融入 js 專案中。


rust & webassembly(wasm) 安全

rust 被證明是可用於大型的、擁有不同層次系統程式設計知識的開發者團隊間協作的高效工具。底層程式碼中容易出現種種隱晦的 bug,在其他程式語言中,只能透過大量的測試和經驗豐富的開發者細心的程式碼評審來捕獲它們。在 rust 中,編譯器充當了守門員的角色,它拒絕編譯存在這些難以捕獲的 bug 的程式碼,這其中包括併發 bug。


使用 rust 構建的區塊鏈專案上,libra 可以說知名度最高,在實現語言上,libra (已更名為 diem ) 專案選擇了一個非常小眾但宣稱安全性突出的語言 rust。然而,宣稱的安全不表示實際上的安全。過於小眾的語言往往缺乏長時間的錘鍊,導致隱藏的問題較多。再安全的語言也無法確保實現的安全,漏洞常常來自程式碼實現過程,來自於人。


rust 社羣也在討論隨機數生成函式的安全升級。所以 rust 語言雖然具有安全的特點,但是並不完美,不排除有可能成為 libra 專案的阿喀琉斯之踵。最後,過於依賴 rust 語言有可能帶來單一性依賴問題,如果 rust 語言出現安全問題,則會波及整個 libra 系統,這一點可能需要時間來解決,畢竟 libra 出現時間尚短,需要時間來實現必要的多樣化部署。


雖然 rust 在編譯時會強制執行的記憶體安全保證。然而,rust 還隱藏有第二種語言,它不會強制執行這類記憶體安全保證:這被稱為不安全 rust ( unsafe rust )。它與常規 rust 程式碼無異,但是會提供額外的超級力量。


比方說有一個 u8 ,它可以存放從零到 255 的值。那麼當你將其修改為 256 時會發生什麼呢?這被稱為 「整型溢位」(「integer overflflow」 ),關於這一行為 rust 有一些有趣的規則。當在 debug 模式編譯時,rust 檢查這類問題並使程式 panic,這個術語被 rust 用來表明程式因錯誤而退出。




在 release 構建中,rust 不檢測溢位,相反會進行一種被稱為二進位制補碼包裝(two’s complement wrapping)的操作。簡而言之,256 變成 0,257 變成 1,依此類推。



近幾年,rust 語言以極快的增長速度獲得了大量關注。其特點是在保證高安全性的同時,獲得不輸 c++/c++ 的效能,讓系統程式設計領域難得的出現了充滿希望的新選擇。在 rust 被很多專案使用以後,其實際安全性表現到底如何呢?


前面有一篇專門針對 rust 安全的研究成果,針對近幾年使用 rust 語言的開源專案中的安全缺陷進行了全面的調查。這項研究調查了 5 個使用rust 語言開發的軟體系統,5 個被廣泛使用的 rust 庫,以及兩個漏洞資料庫。調查總共涉及了 850 處 unsafe 程式碼使用、70 個記憶體安全缺陷、100 個執行緒安全缺陷。


不安全 rust 之所以存在,是因為靜態分析本質上是保守的。當編譯器嘗試確定一段程式碼是否支援某個保證時,拒絕一些有效的程式比接受無效程式要好一些。這必然意味著有時程式碼可能是合法的,但是 rust 不這麼認為!在這種情況下,可以使用不安全程式碼告訴編譯器,「相信我,我知道我在?什麼。」這麼做的缺點就是你只能靠自己了:如果不安全程式碼出錯了,比如解引用空指標,可能會導致不安全的記憶體使用。


另一個 rust 存在不安全一面的原因是:底層計算機硬體固有的不安全性。如果 rust 不允許進行不安全操作,那麼有些任務則根本完成不了。rust 需要能夠進行像直接與作業系統互動,甚至於編寫你自己的作業系統這樣的底層系統程式設計!


總結

不安全的 rust 直接影響了以 rust 構建的 wasm 智慧合約的安全性,例如可能的整數溢位,導致轉賬金額前後出現巨大偏差等。好在編譯器充當了守門員的角色,它拒絕編譯存在這些難以捕獲的 bug 甚至是安全性的程式碼。


下一篇文章會著重介紹基於 rust 構建的 wasm 智慧合約的具體安全性,包括:

  • 溢位
  • 解引用裸指標
  • 呼叫不安全的函式或?法
  • 訪問或修改可變靜態變數
  • 實現不安全 trait
  • 訪問 union 的欄位

請大家持續關注我們實驗室公眾號的推送文章。



知道創宇區塊鏈安全實驗室官網:www.knownseclab.com
知道創宇唯一指定存證平臺:www.attest.im
聯絡我們:[email protected]



知道創宇區塊鏈安全實驗室導航


微信公眾號
@ 創宇區塊鏈安全實驗室


微博
@ 知道創宇區塊鏈實驗室
https://weibo.com/blockchainlab


知乎
@ 知道創宇區塊鏈安全實驗室
https://www.zhihu.com/org/zhi-dao-chuang-yu-qu-kuai-lian-an-quan-shi-yan-shi


twitter
@ks_blockchain_
https://twitter.com/ks_blockchain



免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;