如何在超級鏈開放網(wǎng)絡(luò)上部署和調(diào)用DApp
自建鏈,開發(fā)部署太麻煩?
缺錢少人成本高?
一個(gè)超級鏈開放網(wǎng)絡(luò)統(tǒng)統(tǒng)解決你的問題。
在上期線上公開課中,工程師詳細(xì)介紹了“開放網(wǎng)絡(luò)快速上手秘籍”。
本期超級鏈學(xué)院線上公開課教你如何基于超級鏈開放網(wǎng)絡(luò)快速部署一款DApp。
明星講師超哥主要圍繞以下幾點(diǎn)展開:
1. 智能合約如何與業(yè)務(wù)結(jié)合,使業(yè)務(wù)變?yōu)镈App
2. 鏈上智能合約與業(yè)務(wù)結(jié)合的例子
3. 例子中智能合約扮演的角色
4. 怎么開發(fā)公益基金公示智能合約
5. 如何使用迭代器查詢
6. 智能合約總體功能圖中的權(quán)限管理是什么
7. 如何部署和調(diào)用DApp
Q1:上期我們講了如何部署一個(gè)智能合約,很多人會關(guān)心,智能合約如何跟自己的業(yè)務(wù)結(jié)合使業(yè)務(wù)變成一個(gè)DApp,超哥能給大家介紹下嗎?
好的,一般來說,DApp的核心在于業(yè)務(wù)邏輯和數(shù)據(jù)不再托管在一個(gè)中心化服務(wù)上,而是通過智能合約運(yùn)行在區(qū)塊鏈網(wǎng)絡(luò)這樣的去中心化操作系統(tǒng)上,從而保證了數(shù)據(jù)安全、可信。
在實(shí)際實(shí)現(xiàn)過程中,開發(fā)者大多采用智能合約+用戶界面的形式實(shí)現(xiàn)DApp,用戶界面可以是Web頁面或移動應(yīng)用,實(shí)現(xiàn)用戶交互對接。
Q2:能用舉一個(gè)例子介紹下鏈上的智能合約如何和業(yè)務(wù)結(jié)合嗎?
嗯,最近新冠肺炎疫情讓大家都非常揪心,大家在保護(hù)好自己的同時(shí)也都積極的為湖北貢獻(xiàn)自己的愛心,例如捐款捐物等。
現(xiàn)在有很多公益基金會接受捐款,對于捐贈者而言,自己的捐款是否用在合適的地方是大家都關(guān)心的,而對于公益基金會,構(gòu)建更公開透明的運(yùn)行機(jī)制才能贏得大家的信任。
而區(qū)塊鏈在建立信任上有天生優(yōu)勢,特別是建立在更具有公信力的開放網(wǎng)絡(luò)上。因此,我們可以公益捐款為例,介紹一個(gè)基金會利用開放網(wǎng)絡(luò)智能合約構(gòu)建的公益捐款公示DApp。
這個(gè)樣例中,主要實(shí)現(xiàn)捐贈基金匯總、捐贈資金來源和去向的逐條公示,并對于每個(gè)捐款者可以查到自己的所有捐款記錄,從而做到有據(jù)可查、公開透明。
Q3:那在這個(gè)例子中,智能合約扮演什么樣的角色呢?
智能合約是慈善基金公示的核心,負(fù)責(zé)存儲所有捐贈記錄、支出記錄,并提供對捐贈記錄、支出記錄的查詢以及基金會資金總額的查詢,也就是說最核心的業(yè)務(wù)邏輯都通過智能合約實(shí)現(xiàn),數(shù)據(jù)完全存儲在鏈上。
如上圖所示的公益基金公示DApp,智能合約運(yùn)行在超級鏈開放網(wǎng)絡(luò)上,并對外提供數(shù)據(jù)查詢和寫入接口。數(shù)據(jù)寫入接口主要包括新增支出、新增捐款、數(shù)據(jù)初始化等,數(shù)據(jù)查詢接口主要包括查詢所有支出和捐款明細(xì),按照捐款人查詢等。
同時(shí),寫入接口需要進(jìn)行權(quán)限控制,只有基金會的管理賬戶才有權(quán)限寫入數(shù)據(jù),保證鏈上數(shù)據(jù)不被隨意更改,而基金會每次對數(shù)據(jù)的修改都會記錄在開放網(wǎng)絡(luò)的賬本上,因此保證了數(shù)據(jù)的公開透明。
而建立在智能合約之上的用戶交互層則非常簡單,通過開放網(wǎng)絡(luò)SDK,可以實(shí)現(xiàn)對智能合約訪問的RESTful API,并通過Web或移動程序的方式展現(xiàn)。
Q4:那么下面應(yīng)該是實(shí)際開發(fā)智能合約了,超哥跟大家詳細(xì)介紹下怎么開發(fā)這個(gè)公益基金公示智能合約吧。
嗯,又到了令人開心的編碼環(huán)節(jié)。智能合約開發(fā)首先是設(shè)計(jì)好合約接口和參數(shù)。前面我們已經(jīng)明確了合約需求,因此在接口設(shè)計(jì)上也比較清楚,寫入接口主要包含下面三個(gè),實(shí)現(xiàn)數(shù)據(jù)初始化、新增捐贈記錄、新增支出記錄功能:
讀接口主要包括下面4個(gè),分別提供基金會當(dāng)前概覽數(shù)據(jù),按照捐款人查詢,查詢所有捐款明細(xì),查詢所有撥款支出明細(xì)等:
確定所有接口和參數(shù)后,我們開始設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)。目前C++合約支持KV存儲和Table存儲模型,在本例中,我們選用KV存儲保存數(shù)據(jù)。為了方便遍歷查詢,我們給“所有捐款明細(xì)”、“所有支出明細(xì)”、“捐款人捐款列表”指定不同的Key前綴,方便通過合約SDK中的迭代器進(jìn)行遍歷查詢。以所有捐款明細(xì)為例,數(shù)據(jù)組織方式如下圖所示:
這里的“AllDonate_”是所有捐款明細(xì)列表的Key前綴,后面的“0000000001”是捐款記錄的自增ID編號。而Value則是一個(gè)半結(jié)構(gòu)化數(shù)據(jù),包括捐款者的用戶ID、捐款數(shù)額、時(shí)間、其他備注信息等。
對于按照捐款人維度查詢的接口,則組織Key結(jié)構(gòu)上稍微復(fù)雜一點(diǎn),大致上以“Key前綴+捐款人ID+捐款記錄ID”拼成一個(gè)key,本例中Key前綴是“UserDonate_”,這樣在確定要查詢的捐款人ID后,拼接為“UserDonate_UserID”的key前綴進(jìn)行遍歷。
同時(shí),考慮到要進(jìn)行基金會運(yùn)行概覽的統(tǒng)計(jì),因此需要幾個(gè)全局變量記錄總得金額數(shù)據(jù),分別是:TotalDonates表示總捐款金額,TotalCosts表示總撥付支出金額,Balance表示基金會目前賬面余額。為了維護(hù)自增ID,也需要記錄總捐款記錄數(shù)和總支出記錄數(shù)兩個(gè)統(tǒng)計(jì)值。
數(shù)據(jù)接口確定后,就進(jìn)入了具體的編碼實(shí)現(xiàn)階段了,實(shí)際代碼編寫不詳細(xì)介紹了,這個(gè)公益基金公示智能合約樣例我們開源在了
https://github.com/xuperchain/xuperchain/blob/v3.6/core/contractsdk/cpp/example/charity_demo.cc,大家可以查看完整的合約代碼了解細(xì)節(jié)信息。
Q5:那么如何使用迭代器查詢呢,能舉一個(gè)查詢接口的具體例子嗎?
好的,我們以按照捐款人查詢所有捐款記錄為例介紹下迭代器如何使用。
上面是迭代器查詢的代碼片段,可以看到使用迭代器主要分為幾個(gè)步驟:
1. 首先要確定迭代器遍歷的Key前綴和終止位置,并創(chuàng)建迭代器對象iter。本例中Key前綴就是“UserDonate_UserID%”,而“~”字符這是ASCII表中最后一個(gè)可見字符,所以作為遍歷終止位置。
2. 然后,開始進(jìn)入循環(huán)迭代,“iter-》next()”函數(shù)返回迭代器是否還有下一行符合條件的結(jié)果,如果沒有則循環(huán)結(jié)束。
3. 如果迭代器找到下一行結(jié)果,則通過“iter-》get()”獲取到一個(gè)key-value對,Key中除去前綴部分就是捐款記錄ID,value中這是捐款記錄詳情。
通過上述步驟可以遍歷出捐款人的所有捐款記錄。需要注意的是,迭代器默認(rèn)的一次循環(huán)返回的最大結(jié)果是100行,因此如果記錄數(shù)比較多的情況下,最好是每次傳入一個(gè)起始ID進(jìn)行分頁查詢。在我們的示例代碼中,queryDonates和queryCosts兩個(gè)接口都是傳入一個(gè)查詢起始ID和每頁查詢數(shù)量做分頁查詢,大家可以參照這兩個(gè)接口了解具體實(shí)現(xiàn)。
Q6:之前的智能合約總體功能圖中,還有一個(gè)權(quán)限管理的部分,能詳細(xì)介紹下嗎?
權(quán)限管理主要是對于寫接口進(jìn)行權(quán)限限制,因?yàn)榫杩顢?shù)據(jù)和支出數(shù)據(jù)不是任何人都能隨便寫入的,而是基金會的管理者才有權(quán)限將捐款信息和支出信息寫入智能合約對外公示,因此需要對寫入者的身份進(jìn)行驗(yàn)證。在超級鏈開放網(wǎng)絡(luò)中,我們有兩種方式可以控制哪些人有權(quán)限訪問相應(yīng)的合約接口:
1. 一種是在智能合約的接口實(shí)現(xiàn)代碼中,獲取到合約上下文參數(shù)中的initiator,這個(gè)iniTIator是本次合約調(diào)用的發(fā)起人,開發(fā)者可以判斷調(diào)用者是否是某個(gè)具有管理權(quán)限的address。而具有管理權(quán)限的address則可以在合約部署時(shí)通過iniTIalize函數(shù)參數(shù)寫入智能合約。
2. 另一種是使用超級鏈本身的ACL權(quán)限控制,這種方式支持合約接口級別的ACL權(quán)限配置,可以指定那些address具有訪問某個(gè)接口的權(quán)限,并且ACL配置可以隨時(shí)修改。相對而言,這種方式設(shè)置權(quán)限更為靈活。
而在本例中,我們采用了第一種方法設(shè)置管理權(quán)限,在初始化函數(shù)中通過“admin”參數(shù)寫入一個(gè)管理員賬戶address,后面的寫接口對會對比iniTIator是否是admin賬號。這種硬編碼的方式相對而言更具公信力,但不夠靈活。
Q7:上面我們已經(jīng)完成了DApp中智能合約的設(shè)計(jì)和開發(fā),那么如何部署和調(diào)用呢?
部署的話,智能合約首先需要本地編譯成wasm字節(jié)碼,然后可以通過Go SDK進(jìn)行部署,也可以通過xchain.baidu.com的開放網(wǎng)絡(luò)平臺上傳字節(jié)碼部署。
首先介紹下使用Go SDK部署合約,上一期我們介紹了通過Go SDK如何導(dǎo)入一個(gè)加密的賬戶私鑰,我們進(jìn)一步介紹下如何部署一個(gè)智能合約。在Go SDK中,部署合約已經(jīng)封裝成了很方便的接口,具體的代碼實(shí)現(xiàn)可以參照SDK的樣例代碼:
https://github.com/xuperchain/xuper-sdk-go/blob/master/example/main.go#L124
通過平臺圖形化界面進(jìn)行部署更為簡單方便,可以參考開放網(wǎng)絡(luò)文檔
https://xuperos.readthedocs.io/zh_CN/latest/operaTIon_manuals.html#create
這里也跟大家預(yù)告一個(gè)好消息,超級鏈開放網(wǎng)絡(luò)很快會支持開發(fā)者在線編輯合約代碼、編譯并直接部署,整體易用性進(jìn)一步提升。