王璞巍,楊航天,孟 佶,陳晉川,杜小勇
1(中國(guó)人民大學(xué) 信息學(xué)院,北京 100872)
2(數(shù)據(jù)工程與知識(shí)工程教育部重點(diǎn)實(shí)驗(yàn)室(中國(guó)人民大學(xué)),北京 100872)
通訊作者:陳晉川,E-mail:jcchen@ruc.edu.cn
智能合約(smart contract)的概念由跨領(lǐng)域的學(xué)者Szabo 于1994 年提出[1].Szabo 將智能合約定義為實(shí)現(xiàn)合同條款的計(jì)算機(jī)程序,且在不需要可信第三方情況下,能夠確保合同的正確履行.在區(qū)塊鏈技術(shù)出來(lái)之前,智能合約并未在實(shí)際中應(yīng)用,因?yàn)楹茈y在沒(méi)有可信第三方情況下保證合同的正確執(zhí)行.比特幣系統(tǒng)是第一個(gè)區(qū)塊鏈的應(yīng)用系統(tǒng),也第一次實(shí)現(xiàn)了智能合約的理念.區(qū)塊鏈網(wǎng)絡(luò)所具備的去中心化、去信任以及不可篡改的特質(zhì),使其成為智能合約天然的執(zhí)行平臺(tái).伴隨著區(qū)塊鏈技術(shù)向多個(gè)傳統(tǒng)行業(yè)的滲透,智能合約也得到了廣泛應(yīng)用,其理念和實(shí)現(xiàn)技術(shù)也有了迅速的發(fā)展.與此同時(shí),越來(lái)越多的學(xué)者認(rèn)為,智能合約就是運(yùn)行在區(qū)塊鏈上的程序,不再與合同綁定.本文討論的智能合約是指經(jīng)典的定義,即,用程序定義的合同條款.
在實(shí)際應(yīng)用中,可以通過(guò)智能合約防范履約風(fēng)險(xiǎn),讓合同履行實(shí)現(xiàn)自治,無(wú)需法院等權(quán)威機(jī)構(gòu)來(lái)督促合約的執(zhí)行.隨著區(qū)塊鏈技術(shù)的不斷發(fā)展,智能合約被應(yīng)用到不同領(lǐng)域.以農(nóng)業(yè)保險(xiǎn)為例,農(nóng)業(yè)保險(xiǎn)品種小、覆蓋范圍低,經(jīng)常會(huì)出現(xiàn)騙保事件.將智能合約與農(nóng)業(yè)保險(xiǎn)結(jié)合之后,一旦檢測(cè)到農(nóng)業(yè)災(zāi)害,就會(huì)自動(dòng)啟動(dòng)賠付流程,這樣賠付效率更高[2].此外,在醫(yī)療數(shù)據(jù)共享領(lǐng)域,通過(guò)智能合約來(lái)規(guī)范數(shù)據(jù)的產(chǎn)生者(病人)、數(shù)據(jù)的保管者(醫(yī)院)以及數(shù)據(jù)的使用者(數(shù)據(jù)分析公司)三方的權(quán)責(zé)利,促進(jìn)醫(yī)療大數(shù)據(jù)的共享[3].
雖然智能合約已經(jīng)得到了廣泛應(yīng)用,但一直缺乏嚴(yán)格的定義.目前看到,對(duì)智能合約的描述都是采用自然語(yǔ)言,表達(dá)上不夠精確,且存在分歧.有些文獻(xiàn)認(rèn)為,智能合約應(yīng)該是數(shù)字化的商務(wù)合同.商務(wù)合同是指有關(guān)各方在進(jìn)行商務(wù)合作的時(shí)候需要共同遵守的協(xié)議條款,里面的協(xié)議常常涉及各種商業(yè)邏輯.例如,我們摘取了航班延誤保險(xiǎn)合同的一部分協(xié)議:“被保險(xiǎn)人持本人購(gòu)買的有效機(jī)票以乘客身份乘坐航班時(shí),遭遇搭乘航班較預(yù)定起飛時(shí)間延誤,且延誤時(shí)間達(dá)到保險(xiǎn)單所載明的時(shí)間,保險(xiǎn)人按保險(xiǎn)單所載明金額給付保險(xiǎn)金”.這部分協(xié)議包含的商業(yè)邏輯是“只有當(dāng)被保險(xiǎn)人購(gòu)買了機(jī)票,以乘客身份乘坐航班,且航班延誤時(shí)間超過(guò)預(yù)定時(shí)間,保險(xiǎn)人才會(huì)支付保險(xiǎn)金”.但是,數(shù)字化商務(wù)合同的一個(gè)關(guān)鍵問(wèn)題在于:如何形式化描述這些商業(yè)邏輯.
在實(shí)際應(yīng)用中,幾乎所有的區(qū)塊鏈平臺(tái)都宣稱支持智能合約,但實(shí)現(xiàn)的方式差別較大.比特幣的智能合約類似Forth 語(yǔ)言[4],是基于堆棧的腳本,不支持循環(huán),不是圖靈完備.加上大小的限制,使得比特幣的智能合約只能支持有限的邏輯,通常只作為賬戶擁有者的身份識(shí)別.以太坊的智能合約采用圖靈完備的solidity 語(yǔ)言來(lái)編寫,合約具有狀態(tài).超級(jí)賬本旗下的Fabric(Hyperledger Fabric)平臺(tái)采用Go 語(yǔ)言編寫智能合約,功能強(qiáng)大,但本身并不支持狀態(tài).對(duì)智能合約模糊的、不一致的描述,以及不同的實(shí)現(xiàn),妨礙了公眾對(duì)智能合約的認(rèn)知,影響統(tǒng)一標(biāo)準(zhǔn)的制定,并阻礙行業(yè)的健康發(fā)展.
在很多應(yīng)用場(chǎng)景中,智能合約擔(dān)負(fù)商務(wù)合同的作用.此時(shí),智能合約將面臨兩個(gè)問(wèn)題.
1)如何準(zhǔn)確地描述商務(wù)合同?
2)如何讓程序員之外的人員理解?
商務(wù)合同和智能合約的鴻溝在于:前者采用自然語(yǔ)言,后者是計(jì)算機(jī)程序.未受過(guò)專業(yè)訓(xùn)練的人員,比如企業(yè)的法律顧問(wèn),無(wú)法理解程序,只能在計(jì)算機(jī)專家的幫助下對(duì)比智能合約和商務(wù)合同,這里面的難度和風(fēng)險(xiǎn)顯而易見(jiàn).
本文將提出面向合同的智能合約的形式化定義.該定義將基于合同的基本元素(承諾),用統(tǒng)一的形式化模型來(lái)描述商務(wù)合同和智能合約.這樣做的優(yōu)點(diǎn)在于:首先,給智能合約嚴(yán)格的、統(tǒng)一的定義;其次,領(lǐng)域?qū)<液统绦騿T將可以在雙方都能理解的統(tǒng)一模型下交流,就像數(shù)據(jù)庫(kù)中的概念模型.智能合約的形式化定義可以看成是面向智能合約的建模語(yǔ)言,方便非計(jì)算機(jī)專業(yè)的一般用戶來(lái)描述他們的承諾,再?gòu)倪@些承諾自動(dòng)地(或半自動(dòng)地)轉(zhuǎn)換到智能合約具體的實(shí)現(xiàn)語(yǔ)言(例如solidity 和go).
本文第1 節(jié)將概述目前智能合約在學(xué)術(shù)界和工業(yè)界的進(jìn)展,對(duì)比分析不同的智能合約實(shí)現(xiàn).第2 節(jié)將給出智能合約的形式化定義.第3 節(jié)提出了通用的實(shí)現(xiàn)算法.第4 節(jié)介紹我們?cè)趨^(qū)塊鏈平臺(tái)Hyperledger Fabric 中的參考實(shí)現(xiàn).最后,第5 節(jié)總結(jié)全文并展望未來(lái)工作.
在最早的定義中,智能合約被描述為執(zhí)行合同條款的計(jì)算機(jī)程序[1],或者是數(shù)字化的一組承諾[5],要求智能合約的執(zhí)行無(wú)須可信的第三方.需注意,承諾是合同的基本要素.在Wikipedia 的定義中,智能合約是一種旨在以信息化方式傳播,驗(yàn)證或執(zhí)行合同的計(jì)算機(jī)協(xié)議,允許在沒(méi)有第三方的情況下進(jìn)行可信交易,且這些交易可追蹤且不可逆轉(zhuǎn)[6].不難看出,上述對(duì)智能合約的定義,均要求合約能夠?qū)崿F(xiàn)現(xiàn)實(shí)中商務(wù)合同,且要求合約的執(zhí)行在一個(gè)無(wú)須可信第三方的環(huán)境.我們將其稱為“狹義的”或“經(jīng)典的”智能合約,這也是本文討論重點(diǎn).
隨著區(qū)塊鏈的問(wèn)世,人們終于找到了無(wú)中介的可信計(jì)算環(huán)境.只要網(wǎng)絡(luò)中多數(shù)節(jié)點(diǎn)是正常的,那么整個(gè)網(wǎng)絡(luò)最終的運(yùn)行結(jié)果(共識(shí))也就值得信賴.在這之后,智能合約得到了迅速發(fā)展,其概念也在發(fā)生變化.很多學(xué)者認(rèn)為,智能合約就是運(yùn)行在區(qū)塊鏈上的程序.在文獻(xiàn)[7]中,智能合約被定義為運(yùn)行在區(qū)塊鏈上的腳本,實(shí)現(xiàn)了多步驟過(guò)程的自動(dòng)化.在文獻(xiàn)[8]中,區(qū)塊鏈就是可以被一個(gè)網(wǎng)絡(luò)正確執(zhí)行的計(jì)算機(jī)程序,該網(wǎng)絡(luò)由互不信任的節(jié)點(diǎn)構(gòu)成.Luu 等人[9]則認(rèn)為:智能合約就是運(yùn)行在區(qū)塊鏈上的程序,由共識(shí)協(xié)議保證其正確執(zhí)行.類似的觀點(diǎn)還出現(xiàn)在文獻(xiàn)[10-12]中.我們將這類智能合約稱為“廣義的”智能合約.
此外,文獻(xiàn)[13,14]強(qiáng)調(diào)了智能合約是一個(gè)狀態(tài)機(jī).特別是以太坊中,智能合約的每次執(zhí)行都可以看做是從一個(gè)狀態(tài)轉(zhuǎn)移到另一個(gè)狀態(tài)[14].值得注意的是,商務(wù)合同的執(zhí)行過(guò)程也可以被看做是一個(gè)狀態(tài)機(jī).一份合同的執(zhí)行,正是按照預(yù)先規(guī)定的邏輯在不同狀態(tài)之間轉(zhuǎn)移的過(guò)程.
通過(guò)上面對(duì)智能合約的分析,我們認(rèn)為智能合約是具備以下幾個(gè)性質(zhì)的一段程序.
1)支持復(fù)雜的商業(yè)邏輯;
2)支持狀態(tài)機(jī);
3)可以自動(dòng)執(zhí)行;
4)執(zhí)行的結(jié)果能被參與各方認(rèn)可;
5)無(wú)須可信第三方.
比特幣系統(tǒng)是第1 個(gè)區(qū)塊鏈的應(yīng)用,在比特幣系統(tǒng)中,區(qū)塊鏈的作用僅僅是記錄比特幣在各個(gè)賬戶之間的轉(zhuǎn)移.每一筆交易的輸出(output)中,都需要寫入一段腳本,作為該筆輸出在未來(lái)被使用的條件.大多數(shù)情況下,腳本被用來(lái)檢驗(yàn)output 賬戶擁有者的身份.腳本也可以用來(lái)實(shí)現(xiàn)簡(jiǎn)單的邏輯,比如指定某個(gè)輸出只有在區(qū)塊高度達(dá)到某個(gè)閾值之后才能使用.但總的來(lái)說(shuō),比特幣腳本所使用的語(yǔ)言較為簡(jiǎn)單,難以實(shí)現(xiàn)復(fù)雜的商業(yè)邏輯.此外,每個(gè)輸出只能被使用一次,也不能表達(dá)狀態(tài)機(jī).
相對(duì)于比特幣,以太坊平臺(tái)可以支持各類智能合約.以太坊采用的語(yǔ)言是圖靈完備的,可以支持復(fù)雜的商業(yè)邏輯.智能合約以字節(jié)碼形式存儲(chǔ)于區(qū)塊中,可以被各個(gè)節(jié)點(diǎn)執(zhí)行.合約在發(fā)布之后可以被多次調(diào)用,每次調(diào)用均需從之前的區(qū)塊中讀取合約的狀態(tài)和代碼,而調(diào)用執(zhí)行的結(jié)果也會(huì)存入新的區(qū)塊中.因此,智能合約在以太坊上的執(zhí)行就是一個(gè)狀態(tài)機(jī),只不過(guò)這個(gè)狀態(tài)機(jī)是運(yùn)行在區(qū)塊鏈這個(gè)去中心的分布式計(jì)算平臺(tái)上.
超級(jí)賬本是目前影響最為廣泛的聯(lián)盟鏈項(xiàng)目,其中最重要的系統(tǒng)是Fabric.與以太坊和比特幣不同的是:在Fabric 中,智能合約(即Fabric 中的鏈碼,ChainCode)并不存儲(chǔ)于區(qū)塊,而是一直運(yùn)行在聯(lián)盟節(jié)點(diǎn)之上.鏈碼采用Go 語(yǔ)言,圖靈完備,可以實(shí)現(xiàn)各種復(fù)雜的商業(yè)邏輯.但是鏈碼沒(méi)有狀態(tài).在比特幣或以太坊上運(yùn)行的智能合約可以看做是某個(gè)合約模板的多個(gè)實(shí)例,但是在Fabric 中沒(méi)有合約的實(shí)例,所有對(duì)區(qū)塊鏈上數(shù)據(jù)的讀寫都必須經(jīng)過(guò)鏈碼來(lái)執(zhí)行,類似于MVC 模型中的M(model).
EOS(enterprise operation system)是一款為商用分布式應(yīng)用設(shè)計(jì)的區(qū)塊鏈操作系統(tǒng),旨在實(shí)現(xiàn)分布式應(yīng)用的性能擴(kuò)展.其與比特幣、以太坊不同的是:EOS 采用了DPOS(delegated proof of stake,委托權(quán)益證明)的共識(shí)機(jī)制,同時(shí)對(duì)智能合約系統(tǒng)進(jìn)行優(yōu)化,并支持多種語(yǔ)言編寫合約,為使用者提供一個(gè)沒(méi)有手續(xù)費(fèi)的智能合約使用平臺(tái).
BCOS(BlockChain OpenSource)是聚焦于企業(yè)級(jí)應(yīng)用服務(wù)的區(qū)塊鏈技術(shù)開源平臺(tái).BCOS 由微眾銀行、萬(wàn)向區(qū)塊鏈和矩陣元三方開發(fā),為分布式商業(yè)提供區(qū)塊鏈技術(shù)基礎(chǔ)設(shè)施及服務(wù),并于2017 年7 月31 日完全開源.其智能合約主要使用solidity 語(yǔ)言開發(fā),智能合約設(shè)計(jì)理念與以太坊類似.
在表1 中,對(duì)比分析了上述的智能合約系統(tǒng).可以看出以太坊,EOS,BCOS 對(duì)智能合約的實(shí)現(xiàn)較為完善.而比特幣和Fabric 則存在不足.在第4 節(jié)中,我們將基于Fabric 系統(tǒng)實(shí)現(xiàn)一個(gè)帶有狀態(tài)的智能合約.
Table 1 Comparison of major smart contracts表1 目前主流的智能合約對(duì)比分析
智能合約的安全性一直是人們關(guān)心的問(wèn)題,而由智能合約的漏洞暴露出來(lái)的安全性事件層出不窮,例如2017 年6 月的TheDAO 事件[15].TheDAO 是搭建在以太坊網(wǎng)絡(luò)上的智能合約,黑客利用遞歸函數(shù)的漏洞將面向公眾籌集的350 萬(wàn)個(gè)以太坊代幣轉(zhuǎn)向自己的地址,造成了巨大的經(jīng)濟(jì)損失.2018 年4 月,黑客再次利用BEC 代幣的智能合約漏洞向BEC 代幣發(fā)起攻擊[16],通過(guò)計(jì)算溢出,憑空產(chǎn)生5.7896×1058個(gè)代幣,同時(shí),黑客將這些代幣轉(zhuǎn)移到交易平臺(tái)進(jìn)行拋售,導(dǎo)致BEC 代幣市值幾乎歸零.
目前有多個(gè)公司從事與智能合約的安全性驗(yàn)證工作,如鏈安、慢霧等.傳統(tǒng)的安全公司也在開始進(jìn)軍智能合約安全領(lǐng)域,比如360 公司最近發(fā)現(xiàn)了EOS 平臺(tái)的重大漏洞,在文獻(xiàn)[17]中,提出了一種智能合約的形式化驗(yàn)證方法.
基于以上認(rèn)識(shí),我們以承諾(commitment)作為基本元素來(lái)構(gòu)建智能合約.承諾是商務(wù)合同的基本單位[18],表示一方對(duì)另一方的義務(wù).一份合同通常由一組相互關(guān)聯(lián)的承諾組成.在人工智能領(lǐng)域,有不少關(guān)于形式化描述商業(yè)承諾的工作[19,20].本文將承諾用于描述智能合約,根據(jù)智能合約的特點(diǎn)對(duì)承諾進(jìn)行了重新定義,并在此基礎(chǔ)上完成了智能合約的形式化定義.
定義1(承諾).承諾是一個(gè)五元組C(x,y,p,r,tc),含義是承諾人x(promisor)向被承諾人y(promisee)做出承諾,如果前提p(premise)達(dá)成,就產(chǎn)生結(jié)果r(result).其中,
· 前提p和結(jié)果r的值是布爾值.值為true 表示前提已達(dá)成(或結(jié)果已完成),值為false 表示前提未達(dá)成(或結(jié)果未完成);
· tc(time-constraints)表示該承諾的有效期,tc為true,承諾才會(huì)有效.
一個(gè)承諾的生命周期內(nèi)可能有5 種不同的狀態(tài).
1)激活(act):前提p和結(jié)果r都為false,時(shí)間未超出承諾的有效期.表示承諾有效,在等待前提p的達(dá)成和結(jié)果r的完成;
2)就緒(bas):前提p為true,結(jié)果r為false,時(shí)間未超出承諾的有效期.表示承諾已生效且前提p已經(jīng)達(dá)成,在等待結(jié)果r的完成;
3)滿足(sat):前提p和結(jié)果r都為true.表示前提p已達(dá)成,結(jié)果r也已完成,承諾已被履行;
4)過(guò)期(exp):前提p和結(jié)果r都為false,時(shí)間已超出承諾的有效期.表示在承諾失效時(shí),前提p未能達(dá)成而結(jié)果r也未能完成;
5)違約(vio):前提p為true,但結(jié)果r為false,時(shí)間已超出承諾的有效期.表示當(dāng)承諾失效時(shí),盡管b已達(dá)成了前提p,但a仍然未履行其承諾完成結(jié)果r,已經(jīng)違約.
如圖1 所示:如果在創(chuàng)建承諾時(shí),前提p和結(jié)果r都為false,承諾進(jìn)入激活狀態(tài),我們將這樣的承諾成為有條件承諾,也就是承諾人履行該承諾存在前提條件;如果前提p為true,結(jié)果r為false,承諾進(jìn)入就緒狀態(tài),我們將這樣的承諾成為無(wú)條件承諾,也就是承諾人將無(wú)條件履行該承諾;在激活狀態(tài)下,如果時(shí)間超出了承諾的有效期,前提p和結(jié)果r都未能達(dá)成(完成),承諾進(jìn)入了過(guò)期狀態(tài),此時(shí)承諾已經(jīng)失效;在激活狀態(tài)下,如果前提p達(dá)成(也就是使得p=true),該承諾變成無(wú)條件承諾,進(jìn)入就緒狀態(tài);在就緒狀態(tài)下,如果時(shí)間超出了承諾的有效期,結(jié)果r依然未能完成,承諾進(jìn)入違約狀態(tài),表示承諾人已違約.在就緒狀態(tài)下,在有效期內(nèi),承諾人完成了結(jié)果r(也就是使得r=true),進(jìn)入滿足狀態(tài),表示承諾人履行了其承諾.
Fig.1 The lifecycle of a commitment圖1 承諾的生命周期圖
從承諾生命周期圖中我們可以看到,承諾的有效期與激活狀態(tài)和就緒狀態(tài)有關(guān).本文中,我們將承諾有效期(time constraints)定義如下.
定義2(承諾有效期).承諾有效期是一個(gè)二元組tc:=(pdact,pdbas),其中:pdact表示承諾進(jìn)入激活(act)狀態(tài)之后,對(duì)前提p的完成時(shí)間限制;pdbas表示承諾進(jìn)入就緒(bas)狀態(tài)之后,對(duì)結(jié)果r的完成時(shí)間限制.若這兩個(gè)限制滿足,tc為true;否則,tc為false.
例如,tc=(24,24)表示前提p需要在承諾進(jìn)入激活狀態(tài)24h(默認(rèn)單位為h)之內(nèi)達(dá)成(即pdact=24),否則承諾將進(jìn)入過(guò)期狀態(tài);結(jié)果r需要在承諾進(jìn)入到就緒狀態(tài)之后24h 之內(nèi)完成(即pdbas=24),否則承諾進(jìn)入違約狀態(tài).
在承諾中,前提或結(jié)果可能是預(yù)期的動(dòng)作.例如,商家a向客戶b做出一個(gè)承諾,如果b在系統(tǒng)上預(yù)存100 元貨物錢,a就給b寄出相應(yīng)貨物.這里,前提是預(yù)存錢的動(dòng)作(b在系統(tǒng)上預(yù)存100 元錢),而結(jié)果是寄貨物的動(dòng)作(a給b寄出購(gòu)買的貨物).本文中,我們將動(dòng)作(action)定義如下.
定義3(動(dòng)作).一個(gè)動(dòng)作表示為action:=actname(executor,object,input,output),其中:
·actname是動(dòng)作的名稱,executor是動(dòng)作的執(zhí)行者,object是動(dòng)作的作用對(duì)象,input是輸入?yún)?shù),output是輸出參數(shù)(act,exectuor是必需的(required),而object,input和output都是可選的(optional));
· 動(dòng)作的值是一個(gè)布爾值,action=fasle 表示沒(méi)有完成該動(dòng)作,action=true 表示該動(dòng)作已完成.動(dòng)作的默認(rèn)值為false.
例如,transfer(a,b,10,receipt)表示a向b轉(zhuǎn)賬10 元的動(dòng)作,其中,transfer是動(dòng)作名,a是動(dòng)作的執(zhí)行者,b是動(dòng)作的作用對(duì)象,10 是輸入?yún)?shù),receipt(收據(jù))是輸出參數(shù).transfer(a,b,10,receipt)的默認(rèn)值是false,表示b還沒(méi)有收到a轉(zhuǎn)過(guò)來(lái)的10 元錢,也就是動(dòng)作還未完成.如果transfer(a,b,10,receipt)=true,則表示該動(dòng)作已經(jīng)完成(a收到b轉(zhuǎn)賬過(guò)來(lái)的10 元錢).
此時(shí),前面提到的那個(gè)承諾就可以寫為
這是一個(gè)有條件承諾,其含義是:如果客戶b在承諾激活的24h 內(nèi)達(dá)成前提deposit(b,s,100)=true,那么商家a就會(huì)在承諾就緒后的24h 內(nèi)完成結(jié)果send(a,b,goods)=true.但是假設(shè)有這樣一種情況:如果客戶b在承諾C1進(jìn)入過(guò)期狀態(tài)之后才在系統(tǒng)s上預(yù)存100 元錢,這時(shí)候承諾C1已失效(可能是商家a的優(yōu)惠購(gòu)買活動(dòng)已經(jīng)結(jié)束),系統(tǒng)s如何處理這一筆預(yù)存款呢?此時(shí),系統(tǒng)s往往需要做出一個(gè)關(guān)于“承諾C1過(guò)期之后如何處理客戶預(yù)存款”的承諾.可以看到,承諾的前提可能與另一個(gè)承諾的狀態(tài)有關(guān)系.系統(tǒng)s可以做出如下承諾:
其中,
·C1_exp是一個(gè)布爾變量:如果承諾C1處于過(guò)期(exp)狀態(tài),值為true;否則,值為false;
· 有效期tc=(∞,24)表示承諾在激活狀態(tài)不會(huì)過(guò)期,但如果在就緒狀態(tài)下超過(guò)24h 還未完成結(jié)果,系統(tǒng)s將會(huì)違約.這個(gè)承諾的具體含義是:系統(tǒng)s向客戶b承諾,如果b在承諾C1過(guò)期之后還在系統(tǒng)上預(yù)存錢,系統(tǒng)將會(huì)在24h 內(nèi)退錢給b.
這里,我們通過(guò)一個(gè)機(jī)票延誤險(xiǎn)的案例來(lái)說(shuō)明我們定義的承諾.在機(jī)票延誤險(xiǎn)場(chǎng)景中,乘機(jī)人購(gòu)買機(jī)票之后在系統(tǒng)上預(yù)存10 元保費(fèi);保險(xiǎn)公司再在系統(tǒng)上預(yù)存相應(yīng)的賠償金1000 元;如果保險(xiǎn)公司沒(méi)有按時(shí)預(yù)存賠償金,系統(tǒng)就直接將保費(fèi)退還給用戶;如果保險(xiǎn)公司預(yù)存了賠償金,若航班沒(méi)有延誤,或者延誤時(shí)間少于4h,系統(tǒng)就將乘機(jī)人預(yù)存的保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司,同時(shí)退還保險(xiǎn)公司預(yù)存的賠償金.如果航班延誤超過(guò)4h,系統(tǒng)也會(huì)將保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司,但是會(huì)將保險(xiǎn)公司預(yù)存的賠償金賠償給乘機(jī)人.假設(shè)a表示保險(xiǎn)公司,b表示乘機(jī)人,c表示航空公司,s表示系統(tǒng),MAX-T表示保險(xiǎn)最大有效期,他們的承諾如下.
·C3=C(b,s,true,buy_ticket(b,c,flightno),(∞,24)).含義是乘機(jī)人向系統(tǒng)承諾:將會(huì)向航空公司c購(gòu)買航班號(hào)為flightno的機(jī)票(buy_ticket(b,c,5210)).這個(gè)承諾是無(wú)條件承諾,沒(méi)有前提條件,承諾初始為就緒狀態(tài).承諾有效期是(∞,24),即乘機(jī)人將在24h 購(gòu)買機(jī)票;
·C4=C(b,s,C3_sat,deposit(b,s,10),(24,0.5)).含義是乘機(jī)人向系統(tǒng)承諾:如果承諾C3進(jìn)入滿足狀態(tài)(也就是按時(shí)購(gòu)買了機(jī)票),他就在系統(tǒng)上預(yù)存10 元保費(fèi)(deposit(b,s,10)).承諾有效期是(24,0.5),即乘機(jī)人需要在24h 內(nèi)購(gòu)買機(jī)票,以及乘機(jī)人將在購(gòu)買機(jī)票后0.5h 內(nèi)在系統(tǒng)上預(yù)存保費(fèi);
·C5=C(a,s,C3_sat,C4_sat,deposit(a,s,1000),(72,1)).含義是保險(xiǎn)公司向系統(tǒng)承諾:如果承諾C3和C4都進(jìn)入了滿足狀態(tài)(也就是乘機(jī)人按時(shí)購(gòu)買了機(jī)票并且在系統(tǒng)上按時(shí)預(yù)存了10 元保費(fèi)),它將在系統(tǒng)上預(yù)存1000 元賠償金(deposit(a,s,1000)).承諾有效期是(72,1),即保險(xiǎn)公司只在72h 內(nèi)接受乘機(jī)人預(yù)存保費(fèi),且將在乘機(jī)人購(gòu)買機(jī)票和預(yù)存保費(fèi)之后1h 內(nèi)在系統(tǒng)上預(yù)存賠償金;
·C6=C(s,b,C5_vio,refund(s,b,10),(MAX-T,2)).含義是系統(tǒng)向乘機(jī)人承諾:如果承諾C5進(jìn)入違約狀態(tài)(也就是保險(xiǎn)公司未能按時(shí)預(yù)存保險(xiǎn)金),系統(tǒng)將向用戶退還預(yù)存保費(fèi)(refund(s,b,10)).承諾有效期是(MAX-T,2),即,系統(tǒng)將在保險(xiǎn)公司違約之后2h 內(nèi)退還保險(xiǎn)金;
·C7=C(s,b,C5_satflight_delay(c,flightno,4.0),transfer(s,a,10),compensate(s,b,1000),(MAX-T,24)).含義是系統(tǒng)向乘機(jī)人承諾:如果承諾C5進(jìn)入滿足狀態(tài)(也就是保險(xiǎn)公司預(yù)存了賠償金),并且航空公司c航班號(hào)為flightno的飛機(jī)延誤 4h 以上(flight_delay(c,flightno,4.0)),系統(tǒng)將把 10 元保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司(transfer(s,a,10)),同時(shí)向乘機(jī)人賠償1000 元(compensate(s,b,1000));承諾有效期是(MAX-T,24),即,系統(tǒng)將在完成投保且航班延誤后24h 內(nèi),將保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司和支付用戶賠償金;
·C8=C(s,a,C5_sat?flight_delay(c,flightno,4.0),transfer(s,a,10),refund(s,a,1000),(MAX-T,24)).含義是系統(tǒng)向保險(xiǎn)公司承諾:如果承諾C5進(jìn)入滿足狀態(tài)(也就是保險(xiǎn)公司預(yù)存了賠償金),并且航空公司c航班號(hào)為flightno的飛機(jī)沒(méi)有延誤,或延誤在4h 內(nèi)(?flight_delay(c,flightno,4.0)),系統(tǒng)將把10 元保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司(transfer(s,a,10)),同時(shí)向保險(xiǎn)公司退還1000 預(yù)存賠償金(refund(s,a,1000)).
定義4(智能合約).智能合約就是定義在一組承諾之上的有限自動(dòng)機(jī)SC:=(CC,A,S,s0,δ,F),其中,
·CC={C1,C2,…,Cn}是一個(gè)有限的承諾集合;
·A是這些承諾涉及到的動(dòng)作的集合(包括超時(shí)動(dòng)作,也就是時(shí)間超出了承諾的有效期);
·S={s0,s1,s2,…,sm}是一個(gè)有限的狀態(tài)集合.狀態(tài)si由CC中所有承諾的狀態(tài)共同決定:
·s0是初始狀態(tài),其中,CC中所有承諾或者處于激活狀態(tài)(有條件承諾),或者就緒狀態(tài)(無(wú)條件承諾);
·δ:S×A→S是狀態(tài)變遷函數(shù).A中的動(dòng)作會(huì)促使CC中承諾的狀態(tài)發(fā)生變化,從而引起智能合約的狀態(tài)發(fā)生變化;
·F∈S是一個(gè)有限的終止?fàn)顟B(tài)集合.
智能合約由一組承諾構(gòu)成,例如第2.1 節(jié)給出了機(jī)票延誤險(xiǎn)場(chǎng)景中的6 個(gè)承諾CC={C3,C4,…,C8},這些承諾里涉及的動(dòng)作有:buy_ticket(b,c,5210)乘機(jī)人購(gòu)買機(jī)票,deposit(b,s,10)乘機(jī)人預(yù)存延誤險(xiǎn)保費(fèi),deposit(a,s,1000)保險(xiǎn)公司預(yù)存賠償金,refund(s,b,10)系統(tǒng)退還乘機(jī)人保費(fèi),refund(s,a,1000)系統(tǒng)退還保險(xiǎn)公司預(yù)存賠償金,flight_delay(c,flightno,4.0)航空公司航班延誤超過(guò) 4h,transfer(s,a,10)系統(tǒng)將乘機(jī)人保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司,compensate(s,b,1000)系統(tǒng)向乘機(jī)人支付賠償金,timeout時(shí)間超過(guò)承諾有效期.
承諾是有狀態(tài)的,對(duì)于智能合約的調(diào)用,會(huì)觸發(fā)承諾的狀態(tài)發(fā)生改變.因而,智能合約又是指定義在一組承諾之上的有限自動(dòng)機(jī).如圖2 所示,可以在這些承諾之上生成一個(gè)智能合約(有限自動(dòng)機(jī)),其初始狀態(tài)為s0={C3:bas,C4:act,C5:act,C6:act,C7:act,C8:act},也就是除了承諾C3是就緒狀態(tài)之外,其他的承諾都是激活狀態(tài).在初始狀態(tài)s0上,乘機(jī)人在承諾C3的有效期內(nèi)執(zhí)行購(gòu)買機(jī)票的動(dòng)作buy_ticket(b,c,flightno)之后,智能合約的狀態(tài)就會(huì)變化為s2={C3:sat,C4:bas,C5:act,C6:act,C7:act,C8:act}.也就是承諾C3的狀態(tài)從就緒(bas)變?yōu)闈M足(sat),承諾C4的狀態(tài)從激活(act)變?yōu)榫途w(bas),其余承諾的狀態(tài)沒(méi)有變化.
Fig.2 An example of smart contract圖2 智能合約:有限自動(dòng)機(jī)
為了簡(jiǎn)便,我們用發(fā)生了變化的那些承諾狀態(tài)來(lái)表示智能合約的新狀態(tài).例如,圖2 就將s2表示為C3:sat,C4:bas,因?yàn)閺膕0變化到s2,只有承諾C3和C4的狀態(tài)發(fā)生變化.在s2狀態(tài)下,若乘機(jī)人執(zhí)行預(yù)存保費(fèi)的動(dòng)作(deposit(b,s,10)),智能合約的狀態(tài)就會(huì)變化為s4=C4:sat,C5:bas.緊接著,如果保險(xiǎn)公司執(zhí)行預(yù)存賠償金的動(dòng)作(deposit(a,s,1000)),智能合約的狀態(tài)會(huì)變化為s6=C5:sat.緊接著,如果航班真的發(fā)生了延誤(flight_delay(c,flightno,4)),智能合約進(jìn)入狀態(tài)s8=C7:bas.系統(tǒng)再將保費(fèi)轉(zhuǎn)賬給保險(xiǎn)公司,但將保險(xiǎn)公司1000 元的預(yù)存金賠償給客戶,智能合約的狀態(tài)最終進(jìn)入終止?fàn)顟B(tài)s10=C7:sat.這就是從智能合約從初始狀態(tài)到終止?fàn)顟B(tài)的一條路徑:s0→s2→s4→s6→s8→s10.根據(jù)初始狀態(tài)s0和這條路經(jīng),可以得出終止?fàn)顟B(tài)s10的完整表示{C3:sat,C4:sat,C5:sat,C6:act,C7:sat,C8:act},也就是承諾C3~C5和C7最終進(jìn)入滿足狀態(tài).此外,從圖2 可以看出,這個(gè)智能合約還有多條執(zhí)行路徑.
本節(jié)討論如何在區(qū)塊鏈平臺(tái)上實(shí)現(xiàn)智能合約.考慮到合約內(nèi)容的多樣性,要求區(qū)塊鏈平臺(tái)能夠運(yùn)行圖靈完備的程序.本節(jié)先介紹智能合約在區(qū)塊鏈平臺(tái)的執(zhí)行過(guò)程,然后提出一種通用的算法.
如圖3 所示,合約發(fā)布到鏈上,有一個(gè)初始狀態(tài).每次調(diào)用(包括指令和參數(shù))都需要讀取合約的邏輯和上一個(gè)狀態(tài),執(zhí)行之后將新的狀態(tài)存入?yún)^(qū)塊.智能合約就是運(yùn)行在區(qū)塊鏈上的狀態(tài)機(jī).
Fig.3 The process of executing smart contracts on blockchain platforms圖3 智能合約在區(qū)塊鏈平臺(tái)上執(zhí)行的通用過(guò)程描述
智能合約是一個(gè)狀態(tài)機(jī),因此必然包含狀態(tài)機(jī)和一系列接口函數(shù).對(duì)智能合約的每次調(diào)用,都通過(guò)接口函數(shù)來(lái)完成,相當(dāng)于對(duì)狀態(tài)機(jī)施加的動(dòng)作.狀態(tài)機(jī)將實(shí)現(xiàn)合約所包含的一系列承諾,以及承諾之間的約束.算法1 介紹了對(duì)智能合約的調(diào)用過(guò)程.
算法 1.invokeContract.
注意輸入?yún)?shù)sig,對(duì)合約的每次調(diào)用操作均必須由調(diào)用者簽名.
· 算法第1 步,從區(qū)塊鏈上讀取指定的合約信息,存儲(chǔ)到結(jié)構(gòu)體contractInfo中;
· 第2 步將檢驗(yàn)簽名的有效性,operation相當(dāng)于明文,sig為對(duì)應(yīng)密文,verifySig函數(shù)將嘗試使用調(diào)用者公鑰(invokerID)去驗(yàn)證簽名;
· 第3 步是檢查操作的有效性,根據(jù)合約的邏輯,判斷當(dāng)前狀態(tài)下該調(diào)用者是否可以執(zhí)行相應(yīng)操作.這里,合約的邏輯實(shí)現(xiàn)了所有的承諾以及承諾之間的約束;
· 第4 步將執(zhí)行操作,根據(jù)狀態(tài)轉(zhuǎn)移矩陣修改合約的狀態(tài),并修改合約的屬性值.注意,本次操作和簽名也會(huì)保存作為合約的操作日志;
· 最后一步是將新的合約信息保存到區(qū)塊鏈上.
下面,從兩方面對(duì)算法1 進(jìn)行分析,我們將討論其性能及其在執(zhí)行過(guò)程中如何與外界可信地交互.
算法1 只是一個(gè)框架,在具體執(zhí)行時(shí)會(huì)調(diào)用不同的智能合約,因此整體執(zhí)行性能取決于智能合約的復(fù)雜程度.因此,我們?cè)谶@里只能討論在區(qū)塊鏈環(huán)境中執(zhí)行一些基本操作的時(shí)間開銷.算法1 所涉及的基本操作主要是從區(qū)塊鏈上讀取合約的狀態(tài),以及向區(qū)塊鏈上寫入更新后的合約狀態(tài).通常,讀取操作可以基于節(jié)點(diǎn)的本地狀態(tài)數(shù)據(jù)庫(kù)完成,時(shí)間開銷很小.而寫入操作需要和網(wǎng)絡(luò)中其他節(jié)點(diǎn)保持一致,其時(shí)間開銷主要取決于所采用的共識(shí)協(xié)議類型以及網(wǎng)絡(luò)的規(guī)模.一般而言,公鏈的寫入耗時(shí)較長(zhǎng),如比特幣網(wǎng)絡(luò)在1h 左右(即6 次確認(rèn)),以太坊則在10s 左右.聯(lián)盟鏈的網(wǎng)絡(luò)規(guī)模較小,單次寫入耗時(shí)可以在亞秒級(jí).本文在實(shí)驗(yàn)中采用的是Hyperledger Fabric,在單機(jī)上虛擬多個(gè)節(jié)點(diǎn),實(shí)驗(yàn)中平均每次寫入耗時(shí)約數(shù)百毫秒;
算法1 中對(duì)智能合約進(jìn)行調(diào)用時(shí),有時(shí)會(huì)涉及與外部的交互問(wèn)題,比如確認(rèn)航班是否延誤.目前采用的辦法是利用類似oraclize 這樣的預(yù)測(cè)機(jī),保證各個(gè)節(jié)點(diǎn)拿到可信的相同的外部數(shù)據(jù).Oraclize 依賴于TLS 公證(TLSnotary)來(lái)提供誠(chéng)實(shí)地從互聯(lián)網(wǎng)頁(yè)面安全獲取信息的能力.
本節(jié)將介紹基于Hyperledger Fabric 系統(tǒng)對(duì)航空延誤保險(xiǎn)例子的實(shí)現(xiàn).在第4.1 節(jié)簡(jiǎn)述基于Fabric 平臺(tái)搭建的區(qū)塊鏈網(wǎng)絡(luò);第4.2 節(jié)介紹程序模塊.我們的代碼可以從https://github.com/ RucBlockchain/SmartContract 鏈接下載.
在Hyperledger Fabric 1.0 中有兩種類型節(jié)點(diǎn).一類是peer 節(jié)點(diǎn),負(fù)責(zé)存儲(chǔ)區(qū)塊鏈.Chaincode(鏈碼)部署在peer 節(jié)點(diǎn)上,可以對(duì)區(qū)塊鏈進(jìn)行讀寫.多個(gè)peer 節(jié)點(diǎn)構(gòu)成一個(gè)組織(organization),每個(gè)組織有一個(gè)CA 認(rèn)證中心,負(fù)責(zé)分發(fā)公鑰和私鑰.多個(gè)組織構(gòu)成一個(gè)通道(channel),只有通道內(nèi)的peer 節(jié)點(diǎn)才能參與交易(也就是一個(gè)聯(lián)盟鏈);另一類是orderer(排序)節(jié)點(diǎn),不負(fù)責(zé)存儲(chǔ)區(qū)塊鏈,只負(fù)責(zé)對(duì)peer 節(jié)點(diǎn)提交的交易進(jìn)行排序,批量打包后生成新的區(qū)塊,再發(fā)送到peer 節(jié)點(diǎn)加入到區(qū)塊鏈之中.
我們的實(shí)驗(yàn)構(gòu)建了一個(gè)Hyperledger Fabric 網(wǎng)絡(luò),其中有一個(gè)通道,包含了兩個(gè)組織(org1 和org2),每個(gè)組織里有兩個(gè)peer 節(jié)點(diǎn),另外有3 個(gè)orderer 節(jié)點(diǎn)提供共識(shí)服務(wù).Chaincode 是一段由go 語(yǔ)言編寫的代碼,可以對(duì)區(qū)塊鏈進(jìn)行讀寫操作.如圖4 所示,Hyperledger Fabric 1.0 上,chaincode 的執(zhí)行過(guò)程如下.
1)用戶向某個(gè)peer 節(jié)點(diǎn)(稱為提交節(jié)點(diǎn))發(fā)出調(diào)用chaincode 的請(qǐng)求;
2)提交節(jié)點(diǎn)執(zhí)行chaincode 代碼.當(dāng)需要進(jìn)行交易(就是往區(qū)塊鏈寫入交易)的時(shí)候,向channel 中的幾個(gè)peer 節(jié)點(diǎn)(稱之為背書節(jié)點(diǎn))發(fā)出背書請(qǐng)求;
3)背書節(jié)點(diǎn)模擬執(zhí)行交易(只是模擬,此時(shí)并不會(huì)真正將交易寫入?yún)^(qū)塊鏈),得到模擬執(zhí)行的結(jié)果;
4)提交節(jié)點(diǎn)收集背書節(jié)點(diǎn)返回的模擬結(jié)果;
5)提交節(jié)點(diǎn)向某一個(gè)排序節(jié)點(diǎn)提交交易請(qǐng)求(包括背書結(jié)果);
6)排序節(jié)點(diǎn)是對(duì)收到的交易進(jìn)行批量打包生成新的區(qū)塊;
7)排序節(jié)點(diǎn)將新生成的區(qū)塊發(fā)送到提交節(jié)點(diǎn)所在channel 中的每個(gè)peer 節(jié)點(diǎn);
8)最后,peer 節(jié)點(diǎn)驗(yàn)證區(qū)塊中每個(gè)交易的背書結(jié)果是否符合事先設(shè)定好的要求,只會(huì)將符合要求的交易寫入到區(qū)塊鏈之中.
Fig.4 The process of executing chaincodes on hyperledger fabric 1.0圖4 Hyperledger Fabric 1.0 上,chaincode 的執(zhí)行過(guò)程
在這個(gè)執(zhí)行過(guò)程中,我們發(fā)現(xiàn):1)通過(guò)chaincode 寫入?yún)^(qū)塊鏈的交易都是被背書點(diǎn)驗(yàn)證的,且通過(guò)排序服務(wù)在每個(gè)節(jié)點(diǎn)上都保證了數(shù)據(jù)的一致性,不需要權(quán)威第三方再進(jìn)行驗(yàn)證;但是,2)chaincode 實(shí)際上只提供了訪問(wèn)區(qū)塊鏈的接口(API),不會(huì)記錄chaincode 的狀態(tài)以及實(shí)現(xiàn)狀態(tài)轉(zhuǎn)移.在我們的實(shí)驗(yàn)中,在chaincode 基礎(chǔ)上實(shí)現(xiàn)了一種支持狀態(tài)機(jī)的通用智能合約.
我們基于chaincode 實(shí)現(xiàn)了一個(gè)狀態(tài)機(jī),可以在區(qū)塊鏈存儲(chǔ)智能合約的狀態(tài)以及實(shí)現(xiàn)狀態(tài)轉(zhuǎn)移.如圖5 所示,外部調(diào)用通過(guò)入口函數(shù)進(jìn)行轉(zhuǎn)發(fā).狀態(tài)機(jī)包括初始化模塊、事件響應(yīng)模塊、事件注冊(cè)模塊及具體的action函數(shù).
· 初始化模塊負(fù)責(zé)構(gòu)造一個(gè)合約實(shí)例以及注冊(cè)合約的參與各方;
· 事件注冊(cè)模塊將建立狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)移矩陣,即:接收到某個(gè)事件時(shí),狀態(tài)應(yīng)如何轉(zhuǎn)變;
· 事件響應(yīng)模塊將根據(jù)狀態(tài)轉(zhuǎn)移矩陣和輸入的事件對(duì)狀態(tài)機(jī)的狀態(tài)進(jìn)行修改;
· 最后,action函數(shù)實(shí)現(xiàn)具體的動(dòng)作(action),如buy_ticket,deposit等等.
Fig.5 The architecture of smart contract program圖5 智能合約程序架構(gòu)
在航空延遲險(xiǎn)的例子中,智能合約需根據(jù)航班的信息來(lái)決定是否賠付.在實(shí)際系統(tǒng)中,可以由多家保險(xiǎn)公司或其他機(jī)構(gòu)主動(dòng)獲取航班信息,并寫入?yún)^(qū)塊鏈.智能合約將根據(jù)這些數(shù)據(jù)來(lái)自動(dòng)判定航班是否延誤.多家公司數(shù)據(jù)相互印證,提高了結(jié)果的可信性.此外,由于寫入?yún)^(qū)塊鏈的數(shù)據(jù)將不可更改,客觀上也會(huì)約束保險(xiǎn)公司的行為.
本文總結(jié)了目前智能合約的發(fā)展?fàn)顩r,提出了對(duì)智能合約的形式化定義,以及通用的實(shí)現(xiàn)算法.在目前廣泛使用的聯(lián)盟鏈平臺(tái)Hyperledger Fabric 上實(shí)現(xiàn)了上述算法,檢驗(yàn)了形式化定義和算法的有效性.之后的工作將致力于開發(fā)一種可視化的智能合約的建模工具,使得用戶可以輕松實(shí)現(xiàn)合同向智能合約的轉(zhuǎn)換,并研究智能合約建模語(yǔ)言向程序語(yǔ)言(如go,solidity,Java 等)的映射方法.