【智能合约】编写复杂业务场景下的智能合约——可升级的智能合约设计模式(附Demo)
智能合約的現(xiàn)狀
以太坊在區(qū)塊鏈上實(shí)現(xiàn)了智能合約的概念,用于:同質(zhì)化通證發(fā)行(ERC-20)、眾籌、投票、存證取證等等,共同點(diǎn)是:合約邏輯簡(jiǎn)單,只是業(yè)務(wù)流程中的關(guān)鍵節(jié)點(diǎn),而非整個(gè)業(yè)務(wù)流程。而智能合約想解決的信任傳遞,是環(huán)環(huán)相扣的,如果在傳統(tǒng)系統(tǒng)環(huán)節(jié)被惡意侵入和篡改數(shù)據(jù),那么傳入智能合約的數(shù)據(jù)就是不受到信任的。因此,整體業(yè)務(wù)流程上鏈?zhǔn)侵悄芎霞s發(fā)展的趨勢(shì)。
智能合約的局限
智能合約在早期被設(shè)計(jì)的時(shí)候,并不打算支撐復(fù)雜的業(yè)務(wù)體系,這和它設(shè)計(jì)的初衷相違背:漏洞往往出現(xiàn)在程序員編寫(xiě)的代碼和他想實(shí)現(xiàn)的邏輯之間存在著差距,越是簡(jiǎn)單的代碼越是安全。簡(jiǎn)單和受限訪問(wèn)成了智能合約安全可靠的保障。
因此,智能合約引入了隔離網(wǎng)絡(luò)和文件系統(tǒng)的沙箱環(huán)境、基于棧的編譯器(有限高度的棧深以及僅可訪問(wèn)棧頂16個(gè)元素的限制)、靜態(tài)語(yǔ)言、gasLimit(限定了合約的大小,每個(gè)合約能處理的邏輯有限;限定每個(gè)函數(shù)邏輯的復(fù)雜度,每一步操作都會(huì)消耗gas,以至于連使用循環(huán)都成了奢侈)、嚴(yán)格的內(nèi)存訪問(wèn)限制(每個(gè)合約僅可以訪問(wèn)自己的存儲(chǔ)單元),這就導(dǎo)致了智能合約不同于傳統(tǒng)編程語(yǔ)言,自身就帶著諸多限制。
目前,智能合約仍然處于發(fā)展的早期階段,配套的工具、成熟的框架、第三方包寥寥可數(shù)。因此編寫(xiě)復(fù)雜業(yè)務(wù)場(chǎng)景的智能合約,只能從底層的邏輯開(kāi)始編寫(xiě):編寫(xiě)數(shù)據(jù)庫(kù)模型CURD、跨合約數(shù)據(jù)交互、增強(qiáng)基本數(shù)據(jù)類(lèi)型功能(string類(lèi)型的slice、array的delete),導(dǎo)致開(kāi)發(fā)合約速度的緩慢。
另外,由于區(qū)塊鏈的另外一個(gè)特性:防篡改。這導(dǎo)致了智能合約部署上鏈后,任何人包括合約所有者都不能再進(jìn)行修改。意味著智能合約無(wú)法像傳統(tǒng)應(yīng)用那樣實(shí)現(xiàn)敏捷開(kāi)發(fā),合約的每一個(gè)方法都需要進(jìn)過(guò)大量測(cè)試,保證整個(gè)合約的正確性嚴(yán)謹(jǐn)性。即使保證合約不出問(wèn)題,但業(yè)務(wù)的需求并非一成不變,業(yè)務(wù)變動(dòng),智能合約無(wú)可避免的跟著變動(dòng),那么意味著合約的重新部署,但是舊合約的數(shù)據(jù)是無(wú)法轉(zhuǎn)移到新合約上的;已部署好的合約如果存在漏洞被惡意攻擊,需要有方法能夠盡快停止合約運(yùn)行,保證用戶(hù)數(shù)據(jù)不被篡改,留出時(shí)間讓智能合約的編寫(xiě)者快速修復(fù)漏洞。因此,合約的升級(jí)和管理需要設(shè)計(jì)。
智能合約目前的發(fā)展方向
編寫(xiě)智能合約的程序員目前分為兩派,一派主張合約盡可能的精簡(jiǎn),只有簡(jiǎn)單才不容易出現(xiàn)錯(cuò)誤,只有關(guān)鍵部分上鏈部分;另一派主張信任傳遞的閉環(huán),也就是說(shuō)整個(gè)業(yè)務(wù)邏輯盡可能多的上鏈,例如Polymath,ConsenSys,它們將完整的業(yè)務(wù)流程利用智能合約的方式實(shí)現(xiàn)。
輕量級(jí)的智能合約并沒(méi)有太多的技術(shù)難點(diǎn)可講,真正需要發(fā)展的是智能合約設(shè)計(jì)模式。
目前,已有的官方推薦的工具集, Zeppelin,它提供了:
數(shù)學(xué)計(jì)算
合約所有權(quán)
編碼解碼
加密解密
方便合約編寫(xiě)者調(diào)用,但這些只能是以工具、參考的形式存在,并不能算作真正意義上的設(shè)計(jì)模式。目前Zeppelin社區(qū)也在積極探索智能合約設(shè)計(jì)模式的實(shí)現(xiàn)方式。
Zeppelin社區(qū)目前構(gòu)思了智能合約與邏輯分離的設(shè)計(jì)模式,用于解決智能合約升級(jí)的問(wèn)題。
原文地址:https://blog.openzeppelin.com/proxy-libraries-in-solidity-79fbe4b970fd/
如何利用智能合約實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)場(chǎng)景
目前受限于智能合約的限制,只能實(shí)現(xiàn)業(yè)務(wù)場(chǎng)景中的關(guān)鍵步驟,如果將整個(gè)業(yè)務(wù)放到鏈上執(zhí)行,傳統(tǒng)智能合約的編寫(xiě)方式將不再適用,例如無(wú)法解決合約文件大小的瓶頸、參數(shù)過(guò)多導(dǎo)致棧深錯(cuò)誤、合約之間互相訪問(wèn)存儲(chǔ)數(shù)據(jù)的問(wèn)題等等,這些都會(huì)影響智能合約的編寫(xiě)。目前如何編寫(xiě)能夠承載負(fù)責(zé)業(yè)務(wù)場(chǎng)景的智能合約,已經(jīng)成為行業(yè)共同面臨的挑戰(zhàn)之一。
在這里,我參照傳統(tǒng)MVC設(shè)計(jì)模式、基于關(guān)系型數(shù)據(jù)庫(kù)存儲(chǔ),結(jié)合智能合約自身特性,Zeppelin社區(qū)提供的合約分離理念,初步實(shí)現(xiàn)復(fù)雜業(yè)務(wù)場(chǎng)景的智能合約設(shè)計(jì)模式。
一、針對(duì)業(yè)務(wù)功能處理
每個(gè)業(yè)務(wù)場(chǎng)景包括多個(gè)角色,角色既有單獨(dú)操作,也有與其他角色共同配合的操作。
針對(duì)角色,將其合約拆分成為:入口合約、存儲(chǔ)合約、邏輯合約。
1) 設(shè)計(jì)存儲(chǔ)合約,用于存儲(chǔ)角色模型的數(shù)據(jù),并提供對(duì)外訪問(wèn)的CURD方法,實(shí)現(xiàn)效果等同于MVC中的Model層。
2) 設(shè)計(jì)邏輯實(shí)現(xiàn)合約,利用存儲(chǔ)合約提供的CURD,實(shí)現(xiàn)業(yè)務(wù)邏輯。類(lèi)比于MVC中的Controller層。
3) 設(shè)計(jì)入口合約,用于提供對(duì)外訪問(wèn)的地址,將用戶(hù)的請(qǐng)求轉(zhuǎn)發(fā)至邏輯合約進(jìn)行處理,執(zhí)行的結(jié)果存入存儲(chǔ)合約中。
二、針對(duì)業(yè)務(wù)變動(dòng)及風(fēng)險(xiǎn)處理
考慮到業(yè)務(wù)會(huì)發(fā)生變動(dòng)。將傳統(tǒng)智能合約拆分成:入口合約、存儲(chǔ)合約、邏輯合約,三個(gè)合約各司其職,共同實(shí)現(xiàn)業(yè)務(wù),當(dāng)業(yè)務(wù)發(fā)生變動(dòng)需要修改,修改并重新部署邏輯合約,并將新版本的邏輯合約注冊(cè)到入口合約,即可以解決
1、 合約可實(shí)現(xiàn)性:突破合約大小限制、函數(shù)復(fù)雜度限制
2、 合約可升級(jí)性:地址不變,只對(duì)合約功能進(jìn)行升級(jí)
3、 合約可維護(hù)性:發(fā)現(xiàn)bug時(shí),及時(shí)對(duì)合約進(jìn)行修復(fù)
另外,智能合約繼承自功能開(kāi)關(guān)合約,可以實(shí)現(xiàn)當(dāng)智能合約發(fā)現(xiàn)漏洞時(shí),緊急關(guān)閉某些功能(例如轉(zhuǎn)賬),減少損失。
三、針對(duì)業(yè)務(wù)角色之間的交互處理
智能合約中,數(shù)據(jù)的記錄都是Key-Value形式,類(lèi)似于Redis這樣的數(shù)據(jù)庫(kù),數(shù)據(jù)之間的關(guān)聯(lián)較弱。通過(guò)設(shè)置各個(gè)合約都可以訪問(wèn)的全局存儲(chǔ)合約,記錄各個(gè)入口合約的地址、合約數(shù)據(jù)之間的關(guān)聯(lián)關(guān)系,使各個(gè)合約之間可以數(shù)據(jù)互通。
四、針對(duì)業(yè)務(wù)場(chǎng)景中的執(zhí)行權(quán)限處理
智能合約繼承自所有權(quán)合約,可以限制合約中某些關(guān)鍵方法的操作者,這些操作者可以是個(gè)人賬戶(hù)、也可以是合約賬戶(hù),使合約受控于系統(tǒng)管理員。另外,也提供了權(quán)限轉(zhuǎn)移功能,可以方便的將權(quán)限轉(zhuǎn)移給其他管理員。
智能合約設(shè)計(jì)模式的技術(shù)點(diǎn)
l委托調(diào)用
以上智能合約的拆分,就是依賴(lài)智能合約中委托調(diào)用的特性。
委托調(diào)用,會(huì)保留調(diào)用者的賬戶(hù)與信息,例如User調(diào)用合約A中funcA,funcA委托調(diào)用合約B中的funcB,那么funcB的調(diào)用者就是User,而不是合約A。委托調(diào)用的優(yōu)勢(shì)就是可以保留調(diào)用合約的上下文,只是利用合約B的代碼實(shí)現(xiàn)想要的功能。這樣可以:
減少合約A中的代碼量。
合約B中的邏輯可以隨時(shí)更新。
lFallback機(jī)制
當(dāng)調(diào)用智能合約中未定義的方法時(shí),智能合約會(huì)將調(diào)用者及參數(shù)都傳給一個(gè)錯(cuò)誤處理函數(shù),類(lèi)似訪問(wèn)了網(wǎng)站中不存在的頁(yè)面,會(huì)跳轉(zhuǎn)到404頁(yè)面一樣。正是利用了這個(gè)特性,合約A(上文例子)將在這個(gè)fallback函數(shù)中統(tǒng)一處理這個(gè)未定義方法。
l內(nèi)聯(lián)匯編
智能合約中的委托調(diào)用,只會(huì)返回調(diào)用結(jié)果是True和False,但我們要達(dá)成智能合約的拆分,就要讓委托調(diào)用返回調(diào)用后的結(jié)果,這就需要修改委托調(diào)用的指令集,將結(jié)果返回。通過(guò)內(nèi)聯(lián)匯編,修改智能合約中委托調(diào)用的實(shí)現(xiàn)。
l全局存儲(chǔ)合約
全局存儲(chǔ)合約是模擬傳統(tǒng)key-value數(shù)據(jù)庫(kù),通過(guò)智能合約的方式實(shí)現(xiàn)數(shù)據(jù)庫(kù)的CURD,將系統(tǒng)的配置(比如管理員的地址、Token與穩(wěn)定貨幣的兌換比例等)、各個(gè)模塊入口合約的地址、合約之間的關(guān)聯(lián)關(guān)系存儲(chǔ)起來(lái),打通各個(gè)合約之間的數(shù)據(jù)。
l合約的合理拆分
目前將合約拆分為入口合約、存儲(chǔ)合約、邏輯合約。
入口合約:所有與合約的交互都是通過(guò)入口合約。入口合約記錄了存儲(chǔ)合約地址:通過(guò)委托調(diào)用轉(zhuǎn)發(fā)給邏輯合約處理,修改存儲(chǔ)合約數(shù)據(jù)。記錄了邏輯合約的地址和版本:知道該轉(zhuǎn)發(fā)給哪個(gè)版本的邏輯合約處理。
存儲(chǔ)合約:負(fù)責(zé)存儲(chǔ)數(shù)據(jù),合約的存儲(chǔ)結(jié)構(gòu)不能變,這是底線(xiàn)。類(lèi)比數(shù)據(jù)庫(kù)中的表,一旦設(shè)定就不能輕易修改;訪問(wèn)及修改數(shù)據(jù)的接口,其他合約不能直接訪問(wèn)當(dāng)前合約的數(shù)據(jù),需要通過(guò)外部函數(shù)來(lái)訪問(wèn)和修改,例如java model中的setter和getter 方法,實(shí)現(xiàn)存儲(chǔ)合約的的CURD。
邏輯合約:負(fù)責(zé)處理合約邏輯,通過(guò)組合存儲(chǔ)合約的CURD,實(shí)現(xiàn)復(fù)雜的邏輯。
智能合約框架
l模塊框架
1、 用戶(hù)調(diào)用入口合約函數(shù)。
2、 入口合約委托給邏輯合約處理。
3、 邏輯合約進(jìn)入到入口合約上下文,獲取到存儲(chǔ)合約地址,修改/查詢(xún)存儲(chǔ)合約數(shù)據(jù)。
4、 邏輯合約返回?cái)?shù)據(jù)給入口合約。
5、 入口合約返回?cái)?shù)據(jù)給用戶(hù)。
l 整體框架
智能合約設(shè)計(jì)模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
a) 拆分智能合約,可以繞過(guò)合約大小的限制,實(shí)現(xiàn)復(fù)雜的功能。
b) 可以通過(guò)升級(jí)邏輯合約來(lái)更新智能合約。
c) 可控的智能合約,當(dāng)出現(xiàn)問(wèn)題時(shí),管理員賬戶(hù)可以關(guān)閉關(guān)鍵性操作。
d) 將功能性合約封裝成通用合約,減少重復(fù)部署合約消耗的gas。
e) 通用全局存儲(chǔ),可以滿(mǎn)足任意格式數(shù)據(jù)的存儲(chǔ)與讀取。
f) 合約注冊(cè)表,可以方便合約之間的互相調(diào)用。
缺點(diǎn):
a) 拆分智能合約,合約總體代碼量增加,增加了部署時(shí)gas的消耗。
b) 合約的可讀性大幅下降,用戶(hù)無(wú)法簡(jiǎn)單的讀取合約的邏輯。
c) 鍵值對(duì)的存儲(chǔ)合約操作復(fù)雜。【智能合約】編寫(xiě)復(fù)雜業(yè)務(wù)場(chǎng)景下的智能合約——可升級(jí)的智能合約設(shè)計(jì)模式
Demo地址:https://github.com/NoharaHiroshi/upgradability-solidity-demo
總結(jié)
以上是生活随笔為你收集整理的【智能合约】编写复杂业务场景下的智能合约——可升级的智能合约设计模式(附Demo)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 信用卡附属卡算新户吗?其实很好理解
- 下一篇: 这个录屏工具在 GitHub 火了,33