NEO智慧合約白皮書

NEOWest發表於2018-12-13

NeoContract 白皮書

前言

智慧合約是指能夠自動執行合約條款的計算機程式,它的概念最早是由密碼學家尼克薩博於 1994 年提出的,幾乎與網際網路同齡。由於缺少可信的執行環境,智慧合約並沒有被廣泛應用。

2008 年一位自稱 Satoshi Nakamoto 的人釋出了比特幣,並提出了區塊鏈的概念。在比特幣系統中,Nakamoto 使用了一套指令碼系統來幫助使用者更加靈活地控制自己的賬戶和轉賬流程,這套指令碼系統成為了基於區塊鏈的智慧合約系統的雛形。

2014 年一位叫做 Vitalik Buterin 的少年釋出了以太坊,它提供了一套基於區塊鏈的、圖靈完備的智慧合約系統,使用這套系統可以建立各種基於區塊鏈的分散式應用。

NEO 是一個基於區塊鏈的數字資產及應用平臺,它提供了一套全新的智慧合約系統 NeoContract,並在系統底層提供了數字資產 NeoAsset 與數字身份 NeoID 等功能,使得人們可以非常方便地開展資產數字化業務,而不僅僅是在區塊鏈上建立原生代幣。

本文將詳細介紹 NeoContract 的特點與非技術細節。技術細節請參考技術文件:Docs.neo.org

特點

確定性

如果一個程式在不同的計算機、或者在同一臺計算機上的不同時刻多次執行,對於相同的輸入能夠保證產生相同的輸出,則稱該程式的行為是確定性的,反之則稱該程式的行為是非確定性的。

區塊鏈是一個通過多方儲存、多方計算的方式來實現資料不可篡改、計算結果可信的分散式系統,智慧合約會在區塊鏈網路的多個節點中執行。如果一個智慧合約是非確定性的,那麼不同節點執行的結果就可能不一致,從而導致共識無法達成,網路陷入停滯。因此,在設計智慧合約系統的時候,需要排除一切可能導致非確定性的因素。

時間

獲取系統時間是一個很常用的系統函式,可能會被大量應用在一些具有時效性合約程式中。但是獲取時間是一個非確定性的系統函式,不同的節點呼叫返回的結果也會不一致,在分散式系統中很難獲得統一的精確時間。因此,NeoContract 只提供了基於區塊時間戳的系統呼叫,可以將整個區塊鏈看成一個時間戳伺服器,並取得任意一個區塊被構造時的時間戳。由於 NEO 平均每 15 秒產出一個區塊,那麼合約執行時的時間大約等於最新的區塊時間加上 15 秒左右。

隨機數

很多智慧合約程式會用到隨機數的功能,比如對賭合約和一些小遊戲等,但是隨機函式是一個典型的非確定性函式,每次呼叫都會得到不同的結果。在分散式系統中,解決這個問題的辦法有很多:可以讓全體節點採用相同的隨機種子,這樣整個隨機函式的返回序列都是確定性的,但是這種方法會提前暴露整個隨機結果,使得這種隨機數的實用價值大大降低;另一種方法是讓全體節點進行通訊以協作的方式來生成隨機數,它可以採用一些密碼學技巧來產生公平的隨機數,但缺點是效能非常差,需要額外的通訊開銷;還有一種方法是引入一箇中心化的隨機數提供者,由它來提供隨機數並保證一致性,但是這種方法的缺點是顯而易見的,使用者必須無條件地信任這個提供者。

執行在 NEO 上的智慧合約有兩種方式來獲取隨機數:第一是每個區塊在被構造時,共識節點都會對一個隨機數達成共識並填充到區塊的 Nonce 欄位中,合約程式可以讀取到任意區塊的 Nonce 欄位;第二是合約程式可以利用區塊的雜湊值作為隨機數的生成手段,由於區塊的雜湊值具有一定的隨機性,這種方式可以得到一個較弱的隨機數。

資料來源

如果一個程式在執行時獲取資料,而資料來源提供的是非確定性的資料,那麼該程式也可能會變成非確定性的程式。例如,通過搜尋引擎來獲取某個關鍵詞的前 10 條搜尋結果——搜尋引擎針對不同的 IP 地址來源可能會返回不同的排序結果。

NEO 向智慧合約提供了兩種確定性的資料來源:

  • 區塊鏈賬本

    合約程式可以通過互操作服務來訪問到整個區塊鏈上的所有資料,包括完整的區塊和交易,以及它們的每一個欄位。區塊上的資料都具有確定性和一致性,所以可以安全地被智慧合約訪問。

  • 合約儲存空間

    部署在 NEO 上的每一個合約都有一個僅可由該合約本身來存取的私有儲存區,NEO 的共識機制確保了每一個節點上的儲存狀態都是一致的。

對於需要訪問鏈外資料的情況,NEO 沒有提供直接的方式,需要通過交易來將鏈外資料傳送到鏈內,從而轉化成以上兩種型別的資料來源,才能被智慧合約所訪問。

合約呼叫

NeoContract 的智慧合約具有相互呼叫的能力,但不能遞迴呼叫。遞迴可以在合約內部實現,但不能跨越當前合約的邊界。此外合約之間的呼叫關係必須是靜態的:即無法在執行時指定呼叫的目標。這樣做使得程式的行為在執行前就可以被完全確定,其呼叫關係也可在執行前完全確定,以此為依據可以對多個合約進行動態分割槽,從而實現並行化執行的能力。

高效能

智慧合約的執行環境會對合約的效能起到非常重要的作用。當我們分析執行環境的效能時,有兩個指標是非常關鍵的:第一是指令的執行速度,第二是執行環境本身的啟動速度。對於智慧合約而言,執行環境的啟動速度往往要比指令的執行速度更為重要。智慧合約中較多是一些甚少涉及 IO 操作的邏輯判斷指令,這些指令的執行速度很容易得到優化。而智慧合約每次被呼叫,都必須啟動一個新的虛擬機器 / 容器。因此執行環境本身的啟動速度(啟動一個虛擬機器 / 容器)對智慧合約系統的效能影響更大。

NEO 採用了輕量級的 NeoVM(NEO Virtual Machine)作為其智慧合約的執行環境,它的啟動速度非常快,佔用資源也很小,適合像智慧合約這樣短小的程式。通過 JIT(即時編譯器)技術對熱點智慧合約進行靜態編譯和快取可以顯著提升虛擬機器的執行效率。

擴充套件性

高併發與動態分割槽

當談及一個系統的擴充套件性時,會涉及到兩個方面:垂直擴充套件和水平擴充套件。垂直擴充套件是指對處理流程進行優化使得系統能夠充分利用現有裝置的能力,這種方式很容易就會碰上天花板,一個序列系統的處理能力取決於單臺裝置的硬體極限。當我們需要對系統進行擴充套件時,如果有辦法將序列系統改造成並行系統,那麼理論上我們只需要增加裝置的數量,就可以獲得近乎無限的擴充套件性,這種方式就是橫向擴充套件。我們在考慮對區塊鏈系統進行擴充套件時,是否有無限擴充套件的可能?換言之,區塊鏈能否並行地對業務進行處理?

區塊鏈是一個分散式的大賬本,裡面記錄了各式各樣的狀態資料,同時也記錄了這些狀態如何變化的規則,智慧合約正是用來記錄這些規則的載體。區塊鏈能否並行地對業務進行處理,就取決於多個智慧合約能否併發執行——即合約的執行是否是順序無關的。從根本上來說,如果合約之間不會相互影響,或者說如果合約不會同時對相同的狀態資料進行修改,那麼它們的執行就是順序無關的,可以併發執行,否則就只能序列執行,無法橫向擴充套件。

基於上面的分析,我們可以很容易設計出一個具備“無限擴充套件”能力的智慧合約系統。只需要簡單地規定:

  • 一個智慧合約只能修改屬於該合約自己的狀態記錄;

  • 同一個事務批次(區塊)中,一個合約只能被執行一次;

這樣一來,所有的智慧合約之間都是順序無關可以平行處理了。但是,如果“一個智慧合約只能修改屬於該合約自己的狀態記錄”,就意味著合約間無法相互呼叫,每個合約都是一個孤島;如果“一個區塊中,一個合約只能被執行一次”,就意味著用智慧合約發行的某種數字資產在一個區塊裡只能處理一筆交易。這顯然和“智慧”二字的設計初衷大相徑庭。畢竟合約間的相互呼叫,同一區塊中多次呼叫同一個合約,都是我們想要的設計目標。

好在,NEO 的智慧合約之間的呼叫關係是靜態的,無法在執行時指定呼叫的目標。這樣做使得程式的行為在執行前就可以被完全確定,其呼叫關係也可在執行前完全確定。我們要求每一個合約都顯式地申明自身可能會呼叫哪些合約,從而使執行環境能夠在執行合約程式之前,先計算出完整的呼叫樹,並根據這個呼叫樹來對合約的執行進行分割槽,讓可能會對相同狀態記錄進行修改的合約在同一個分割槽中序列執行,而分割槽與分割槽之間可以併發執行。

低耦合

耦合是指兩個或兩個以上的實體相互依賴於對方的一個量度。NeoContract 的系統採用低耦合的設計,合約程式在 NeoVM 中執行,並通過互操作服務層與外部通訊。因此,對智慧合約功能的絕大部分升級,都可以通過增加互操作服務的 API 來實現。

合約用途

驗證合約

與比特幣的公鑰賬戶體系不同,NEO 的賬戶系統採用了合約賬戶體系。NEO 中的每一個賬戶都會對應一個驗證合約,驗證合約的雜湊值即為賬戶地址;而驗證合約的程式邏輯則控制著該賬戶的所有權。當從一個賬戶中轉賬時,需要執行該賬戶所對應的驗證合約。驗證合約可以接受一組引數(通常是數字簽名或者其它判斷條件),並在驗證後返回一個布林值,用於向系統表明本次驗證是否成功。

使用者可以事先將驗證合約部署到鏈上,也可以在轉賬的過程中直接在交易中公佈合約內容。

應用合約

應用合約通過一種特殊的交易來觸發,且可以在執行時訪問和修改系統的全域性狀態及合約的私有狀態(儲存區)。例如,可以在合約中建立全域性數字資產、投票、儲存資料等,甚至在合約執行時動態建立一個新的合約。

應用合約的執行需要按指令進行計費,當交易中的手續費被全部消耗完之後,合約將會失敗並停止執行,同時回滾所有的狀態變化。合約執行的成功與否,不影響其所在交易的有效性。

函式合約

函式合約用於提供一些公共或者常用的功能,以供其它合約來呼叫。它使得智慧合約的程式碼可以被重用,從而使開發者可以編寫出更復雜的業務邏輯。每一個函式合約在被部署的時候,可以選擇是否擁有一個私有的儲存區,該儲存區可在日後被授權的合約讀取或者寫入資料,從而實現狀態持久化的功能。

函式合約必須事先部署到鏈上才能被呼叫,並通過“自毀”的系統函式來從鏈上刪除,刪除後將無法再被使用,且它的私有儲存區也會被銷燬。可以通過合約遷移的方式,將舊合約的資料在銷燬之前自動遷移到子合約中。

虛擬機器

虛擬硬體

NeoVM 提供了虛擬硬體層來對智慧合約的執行提供支援,它們包括:

CPU

CPU 負責讀取並按順序執行合約中的指令,根據指令的功能進行流程控制、算數運算、邏輯運算等。未來可以對 CPU 的功能進行擴充套件,引入 JIT(即時編譯器)的功能,從而提高指令的執行效率。

呼叫棧

呼叫棧用於儲存每一次函式呼叫時程式執行的上下文資訊,以便在函式執行完畢並返回後,能夠繼續在當前的上下文中執行。

計算棧

NeoVM 中所有的執行時資料都存放在計算棧中,當執行不同的指令時,會對計算棧中的資料元素進行相應的操作。例如執行加法指令時,會將參與相加的兩個運算元從計算棧中彈出,並將相加後的運算結果壓入棧頂。函式呼叫的引數也必須按從右到左的順序壓入計算棧,函式執行完畢後可以從棧頂取回函式返回值。

備用棧

當需要對計算棧中的元素進行排程或重新排列時,可以臨時將計算棧中的元素存入備用棧,並在將來取回。

指令集

NeoVM 提供了一套簡單而實用的指令集,用於構造智慧合約程式。按功能劃分,主要包含以下幾類:

  • 常數指令

  • 流程控制指令

  • 棧操作指令

  • 字串指令

  • 邏輯運算指令

  • 算數運算指令

  • 密碼學指令

  • 資料操作指令

值得注意的是,NeoVM 的指令集中內建提供了一系列的密碼學指令,如 ECDSA、SHA 等演算法,以優化智慧合約中用到密碼學演算法時的執行效率。此外,資料操作指令直接對陣列及複雜資料結構提供支援。

互操作服務層

智慧合約執行所在的虛擬機器是一個沙箱環境,當合約需要訪問沙箱外的資料或者將執行時資料持久化儲存時,就需要用到互操作服務層,它為虛擬機器中執行的智慧合約提供了對外溝通的媒介。NeoContract 在互操作服務層中,向智慧合約程式公開了一系列的系統函式和服務,合約可以像呼叫普通函式一樣訪問它們,所有系統函式都是可併發的,所以無需擔心擴充套件性問題。

除錯功能

通常,智慧合約的開發過程是非常困難的,因為沒有良好的除錯和測試方法。NeoVM 在虛擬機器層面提供了程式除錯功能的支援,可以對合約程式碼設定斷點,還可以單步、單過程執行等。得益於虛擬機器與區塊鏈之間的低耦合設計,可以很方便地將 NeoVM 與各種 IDE 直接整合,從而提供一個與最終生產環境一致的測試環境。

高階語言

C#, VB.Net, F#

開發者可以直接使用幾乎任何他們擅長的高階語言來進行 NeoContract 的開發工作。第一批被支援的語言是 C#、VB.Net、F# 等,我們提供了這些語言的編譯器和外掛,用於將高階語言編譯成 NeoVM 所支援的指令集。由於編譯器會針對 MSIL(微軟中間語言)來進行編譯,所以理論上任何 .Net 中的語言或者可被轉譯成 MSIL 的語言都可以直接被直接支援。

這些語言的開發者人數眾多,且具有非常強大的整合開發環境,開發者可以在 Visual Studio 中進行程式碼的編寫、生成、測試、除錯等一系列的開發工作,同時還可以利用我們提供的智慧合約開發模板來進行快速入門。

Java, Kotlin

Java、Kotlin 等語言是第二批被支援的語言,我們提供這些語言的編譯器和 IDE 外掛,來幫助開發者使用基於 JVM 的語言來開發 NEO 的智慧合約應用。

Java 的使用非常廣泛,而 Kotlin 最近也成為了 Google 官方推薦的 Android 開發語言,相信它們能為 NEO 帶來大量的智慧合約開發者。

其它語言

後續,NeoContract 將依據難易程度來分批次開發各種其它高階語言的編譯器,可能會有這些語言:

C, C++, GO

Python, JavaScript

未來會陸陸續續增加新的高階語言支援,使得 90% 的開發者無需學習新的語言即可參與到 NeoContract 的開發中來,甚至可將現有業務系統中的程式碼直接移植到區塊鏈上。

服務

區塊鏈賬本

NEO 的智慧合約可以在執行時通過互操作服務提供的系統函式,獲取 NEO 區塊鏈的完整賬本資料,包括完整的區塊和交易,以及它們的每一個欄位。具體可以查詢到這些資料:

  • 區塊鏈的高度;

  • 區塊頭、區塊;

  • 交易;

  • 交易的型別、屬性、輸入、輸出等;

透過這些資料,可以開發出一些有意思的應用,比如自動權益分紅、基於智慧合約的工作量證明等。

數字資產

通過互操作服務提供的數字資產介面,智慧合約不但可以查詢到 NEO 區塊鏈上各種數字資產的屬性和統計資訊,還可以在執行時建立新的數字資產。由智慧合約所建立的數字資產,可以在合約外部進行發行、轉賬、交易等操作,它們與 NEO 上的原生資產一樣,可以用任何與 NEO 相容的錢包軟體來管理。具體的介面主要有這些:

  • 資產屬性查詢;

  • 資產統計資料查詢;

  • 資產生命週期管理:建立、修改、銷燬等;

  • 資產管理:多國語言的名稱、總量變更、精度變更、管理員變更等;

持久化

每一個被部署到 NEO 區塊鏈上的智慧合約程式,都會擁有一個只有該合約本身可以讀寫的私有儲存區。智慧合約對自己儲存區中的資料擁有完全的操作許可權:可以讀取、寫入、修改、刪除。資料以鍵值對的形式來存放,並提供這些介面:

  • 遍歷儲存區中的所有記錄;

  • 根據指定鍵返回特定記錄;

  • 根據指定鍵來修改或寫入新的記錄;

  • 根據指定鍵來刪除記錄;

一般,合約只能對自己儲存區中的資料進行讀寫,但有一個例外:當發生合約相互呼叫的時候,被呼叫合約可以通過跨域請求來訪問呼叫者的儲存區,前提是呼叫者向其提供了授權。此外,對於在合約執行時動態建立的子合約,父合約會即時獲得其儲存區的讀寫許可權。

跨域請求使得 NeoContract 可以實現更加豐富的庫功能,這些庫可以為呼叫者提供高度封裝的資料管理能力。

費用

部署費用

NEO 的分散式結構提供了高冗餘的儲存能力,對這種能力的使用不是無償的。在 NEO 上部署智慧合約需要支付一筆費用,這筆費用目前固定為 500GAS,由系統收取併成為系統收益。未來可能會根據系統執行的實際情況來調整價格。部署在區塊鏈上的智慧合約可以被多次使用,直到該合約被部署者銷燬。

執行費用

NEO 為智慧合約提供了一個可信的執行環境,而合約的執行也需要消耗各個節點的計算資源,因此使用者需要為智慧合約的執行支付費用。費用的數量由每一次執行所消耗的計算資源決定,計價單位也是 GAS。如果執行過程中由於費用不足導致智慧合約執行失敗的,已被消耗的費用不會退回,這可以防止惡意攻擊對全網算力的消耗。

對於大多數簡單的合約,它們都可以在 10GAS 的免費額度內順利執行完畢,從而大大降低了使用者的使用成本。

應用場景

超導交易

區塊鏈上的數字資產天生具有流動性的需求,通常點對點的交易無法提供足夠高的流動性,因此需要由交易所來為使用者提供交易服務。數字資產的交易所一般會分為兩類:第一類是中心化交易所,使用者需要將數字資產充值到交易所,然後在網站上掛單進行撮合交易;第二類是去中心化交易所,它的交易系統內建在區塊鏈系統中,由系統提供撮合服務。

中心化交易所能夠提供非常高的效能和多樣化的服務,但需要有較強的信用保證,否則將會出現道德風險,比如挪用使用者資金、跑路等。相對的,去中心化交易所雖然沒有道德風險,但是使用者體驗較差,效能上也有較大的瓶頸。有沒有辦法將兩者的優點結合起來,提供一個兩全其美的方法?

超導交易就可以做到這一點,它是這樣一種機制:使用者無需充值,就可以直接使用自己在區塊鏈上的資產來進行交易,交易的結算在鏈上完成,但撮合的過程在鏈外進行,由一箇中心化的交易所來提供撮合服務。由於撮合在鏈外,它的效率可以像中心化交易所一樣高,但資產還在使用者的控制之下,交易所可以根據使用者的交易意願來進行撮合服務,卻無法挪用資金或者跑路,沒有道德風險。

目前,NEO 社群中已經出現一些利用智慧合約來實現區塊鏈超導交易的專案,例如藍鯨淘。

智慧基金

基於區塊鏈的智慧基金具有去中心化、公開透明、隨時加入和退出等特點,相比傳統的基金模式,具有更高的安全性和自由度,還能夠跨越國界,接受全世界投資者的資金,以及投資全世界的優秀專案。

Nest 是一個基於 NeoContract 的智慧基金專案,它和基於以太坊的 TheDAO 專案非常相似,但試圖通過一些方法來提高安全性,避免重蹈 TheDAO 的覆轍(被黑客攻破)。

跨鏈互操作

可以預見,在未來較長的一段時間內,世界上將會有若干公有鏈以及成千上萬的聯盟鏈和私有鏈共存。這些獨立的區塊鏈系統都是價值與資訊的孤島,彼此之間無法互聯互通。通過跨鏈互操作機制,可以將無數個孤立的區塊鏈連線起來,使得不同的區塊鏈上的價值可以相互交換,形成真正的價值網際網路。

NeoContract 為跨鏈互操作的實現提供支援,不但可以實現跨鏈資產交換,還可以執行跨鏈分散式事務,在不同區塊鏈上執行智慧合約,並保證它們的一致性。

預言機

一部預言機可以視為是與一個預言者(oracle)相連線的圖靈機。所謂預言者的概念,是一個可以回答特定問題集合的一個實體。在區塊鏈中,預言機為智慧合約開啟了外部世界的大門,使得智慧合約可以將真實世界的資訊作為合約執行的條件。

NeoContract 沒有提供直接訪問外部資料的能力,比如訪問網際網路上的資源等,因為這樣做會引入非確定性,使得各個節點對合約執行的結果出現不一致。在 NeoContract 中實現預言機,需要由可信的第三方將外部資料通過交易的形式傳送到區塊鏈上,使得這些資訊成為賬本資料的一部分,從而消除非確定性。

前文中提到的可信第三方,可以是一個由合約締造者雙方共同信任的人或機構,也可以是一個去中心化的由經濟激勵來保證的資料提供程式,可以用 NeoContract 來實現這樣一個預言機。

以太坊系列 DAPP

比特幣開創了區塊鏈及電子現金的時代,以太坊則開創了智慧合約的時代。以太坊作為區塊鏈智慧合約的先驅,為智慧合約系統的設計思想、經濟模型、技術實現等方面均做出了巨大的貢獻。同時,以太坊平臺上也已經存在了大量的 DAPP(分散式應用程式),這些 DAPP 的功能各異,有對賭協議、數字資產、電子黃金、遊戲平臺、醫療保險、婚戀平臺,覆蓋各行各業。所有這些 DAPP,理論上都可以很方便地移植到 NeoContract 平臺上,成為 NEO 的應用。

原文連結:docs.neo.org/zh-cn/basic…


相關文章