BSN智能合約開發培訓-FISCO BCOS(二)

  

17119cfb942c3a49?w=468&h=444&f=jpeg&s=38615

作者:微衆銀行

        作爲BSN首個引入的國產聯盟鏈底層框架,FISCO BCOS將在4月份完成BSN適配並開啓公測,屆時,開發者可以免費部署一個具有三個記賬節點的應用。

  目前,FISCO BCOS平臺支持Solidity和Precompiled兩種類型的智能合約,同時,提供交互式控制檯工具(Console),方便開發者與鏈進行交互,部署、調用智能合約。

  爲了讓大家快速上手智能合約,FISCO BCOS推出了智能合約系列教程,本文爲系列教程精編,更多實操內容敬請關注FISCO BCOS開源社區公衆號。

1585275835208719.jpg

  1.智能合約簡介

  衆所周知,智能合約的出現,使區塊鏈不僅能處理簡單的轉賬功能,還能實現複雜的業務邏輯,極大地推動了區塊鏈技術發展,加速應用落地。

  目前,在衆多區塊鏈平臺中,大多數集成了以太坊虛擬機,並使用Solidity作爲智能合約開發語言。作爲一門面向合約的高級編程語言,Solidity借鑑了C++、Python和JavaScript等語言的設計,使用靜態類型,不僅支持基礎/複雜數據類型操作、邏輯操作,同時提供高級語言的相關特性,比如繼承、重載、庫和用戶自定義類型等。

  作爲最大最活躍的國產開源聯盟鏈社區,FISCO BOCS無縫支持Solidity合約,並提供從開發、編譯、部署到調用的全鏈路工具和完整解決方案,使智能合約和區塊鏈應用開發變得簡單。

  除此之外,基於大量探索和實踐,FISCO BCOS不僅支持Solidity合約,還支持Precompiled合約,並在用戶層提供CRUD合約接口。面向庫表開發的CRUD合約不僅更符合用戶開發習慣,進一步降低合約開發難度,提升性能,使區塊鏈應用滿足高併發場景的訴求。

  2.智能合約分類

  FISCO BCOS平臺支持兩種類型的智能合約:Solidity合約和Precompiled合約。

  2.1 Solidity合約

  Solidity合約運行在EVM上,EVM爲以太坊虛擬機,採用哈佛架構,指令、數據和棧完全分離。

  在智能合約運行期間,首先創建一個沙盒環境(EVM實例),沙盒環境與外部環境完全隔離,無法訪問網絡、文件系統其它進程,智能合約在EVM內只允許進行有限的操作。交易執行時,EVM通過獲取合約的opcode,將opcode轉化爲對應的EVM指令,並按照指令進行執行。

  從應用落地的數量來看,Solidity合約使用最爲廣泛,幾乎所有區塊鏈平臺都支持,但Solidity也有很多缺點。如下:

  ●合約在EVM中串行執行,性能較差;

  ●跨合約調用會新建EVM,內存開銷較大;

  ●合約變量和數據存在MPT數中,不便於合約升級;

  ●邏輯和數據耦合,不便於存儲擴容。

  2.2 Precompiled合約

  Precompiled合約即預編譯合約。預編譯合約通過Precompiled引擎執行,採用C++編寫合約邏輯,合約編譯集成進FISCO BCOS底層節點。

  調用合約不進EVM,可並行執行,突破EVM性能瓶頸;提供標準開發框架,只需繼承基類,實現call接口即可;適合於邏輯相對確定、追求高併發的場景;數據存在表中,與合約分離,可升級合約邏輯。

  當然,預編譯合約的使用有一定的門檻。如下:

  ●對於數據的存儲,需要創建FISCO BCOS特有的表結構;

  ●編寫合約時需繼承Precompiled類,然後實現Call接口函數;

  ●完成合約開發後,需在底層爲預編譯合約註冊地址;

  ●編寫完成合約後,需要重新編譯FISCO BCOS源碼。

  爲了屏蔽預編譯合約在開發和使用中的門檻,FISCO BCOS基於預編譯合約和分佈式存儲設計了CRUD合約接口。用戶在編寫Solidity合約時,只需要引入抽象合約接口文件Table.sol,便可使用CRUD功能,用戶不需要關心底層的具體實現。

  3.智能合約開發

  本節將基於全球英文認證考試成績管理作爲場景,基於FISCO BCOS平臺對智能合約進行開發。全球認證考試包括GRE、TOEFL、IELTS等。爲了簡化合約邏輯,所有成績統一由考試管理中心發佈和管理,學生可以根據自己的賬號(地址)查詢自己的考試成績。

  3.1 Solidity合約開發

  在 Solidity 中,合約類似於面向對象編程語言中的類。Solidity合約有自身的代碼結構,由幾個部分組成,如下所示。

  ●狀態變量:狀態變量是永久存儲在合約中的值

  ●構造函數:用於部署並初始化合約

  ●事件:事件是能方便地調用以太坊虛擬機日誌功能的接口

  ●修飾器:函數修飾器可以用來改變函數的行爲,比如自動檢查,類似Spring的AOP

  ●函數:函數是合約中代碼的可執行單元

  ■創建合約

  首先創建一個名爲StudentScoreBySol的合約,用於管理學生的成績。如下代碼所示,開頭需要引入合約版本。

1585275835247170.jpg

  ■定義狀態變量

  狀態變量用於存儲和管理學生的考試成績。

  在當前場景中定義兩個變量,其中_owner爲合約的創建者,即考試管理中心;_scores用於存儲學生成績,爲一個嵌套mapping類型,第一個mapping的key(address)爲學生的賬戶(私鑰對應的地址),value也爲一個mapping類型,對應爲每一科的成績,在第二個mapping中key(bytes32)爲科目名稱,如GRE、TOEFL等,value(uint8)爲成績。如下所示。

1585275835288219.jpg

  ■定義事件

  定義一個事件setScoreEvent,用於跟蹤對學生成績的新增/修改操作,可以在業務層面對事件進行監聽。事件的定義是可選的,如果沒有定義也沒關係,在業務層面可以根據方法的返回值去判斷交易是否成功,但無法做到更精細的問題定位。

1585275835331197.jpg

  ■定義修飾器

  智能合約中的修飾器(Modifier)類似面向對象編程中的AOP,滿足條件纔會執行後續操作。如下所示,修飾器要求必須是合約的Owner才能進行後續操作,其中Owner爲考試管理中心。

1585275835396551.jpg

  ■定義構造方法

  構造方法用於實例化合約,在當前構造方法中,指定Owner爲合約的部署者。

1585275835470531.jpg

  ■編寫函數

  當前合約中,定義兩個函數,setScore函數用於新增/修改/刪除(score置爲0)學生成績,並使用了onlyOwner修飾器,只有Owner(考試管理中心)才能操作,並通過setScoreEvent事件跟蹤每次操作內容。getScore方法用於成績查詢,其中view修飾符表示不會修改狀態變量。

1585275835506365.jpg

  Solidity合約完整代碼如下所示。基於Solidity語言的合約開發,看似簡單,但需要對Solidity編程語言深入學習,才能編寫出高可用的合約,具備一定學習成本。

  通過FISCO BCOS開源社區推出的智能合約專題,開發者可瞭解更多運用Solidity編寫智能合約的方法與技巧,關注“FISCO BCOS開源社區”公衆號可獲取專題。

  更多細節可參考Solidity官方文檔:

  https://solidity-cn.readthedocs.io/zh/develop/

1585275835537046.jpg

  3.2 CRUD合約開發

  CRUD合約是CRUD功能的核心,用戶可以直接在合約中引用CRUD接口文件Table.sol,並在Solidity合約中調用CRUD接口。CRUD合約的開發完全遵從數據庫的操作習慣,更容易理解和上手。

  CRUD合約更多開發細節可參考:

  https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/smart_contract.html#crud■創建合約

  CRUD創建的合約和Solidity創建的沒有太大區別,唯一區別在於需要引入CRUD接口文件Table.sol,如下所示。修飾器和構造方法的作用與Solidity合約相同。

1585275835574865.jpg

  ■事件定義

  在Solidity合約中可以通過setScore完成成績的新增/修改/刪除,但在CRUD合約中,需要藉助CRUD接口文件的不同接口,通過不同函數實現,所以需要針對不同的函數定義不同時間,如下所示。

1585275835617615.jpg

  ●createEvent:用於跟蹤創建表操作;

  ●insertEvent:用於跟蹤插入成績操作;

  ●updateEvent:用於跟蹤更新成績操作;

  ●removeEvent:用於跟蹤刪除成績操作。

  ■創建表函數

  CRUD合約實現業務功能,首先需要像數據庫操作一樣,創建一張表,用於存放數據。

  FISCO BCOS底層提供了TableFactory合約,該合約的地址固定爲0x1001,可以通過TableFactory對象提供的方法對錶進行創建(createTable)和打開(openTable),如下所示。

  createTable接口返回值爲0時,說明創建成功。需要注意的是,爲了讓創建的表可被多個合約共享訪問,表名必須是羣組內全局可見且唯一的,無法在同一條鏈上的同一個羣組中,創建多個名稱相同的表。

1585275835656917.jpg

  ■新增成績函數

  對錶進行操作時,首先需要通過TableFactory打開對應的表,獲得表對象,然後通過表對象的insert方法進行數據插入。在插入數據前,首先需要構建一個Entry對象實例,代碼如下所示。

1585275835704723.jpg

  需要注意的是,Table接口合約的insert、remove、update和select函數返回值類似數據庫,均爲受影響的記錄行數,且接口中key的類型爲string。

  而在當前場景中,學生的studentId爲address類型,所以需要在函數內部將address類型轉化爲string類型,代碼如下。

1585275835737272.jpg

  ■更新成績函數

  更新成績操作步驟包括:通過TableFactory對象打開表,然後,像數據庫一樣構造篩選條件。

  在CRUD合約接口中,提供了Condition對象,該對象提供了諸如大於、等於、小於等一系列條件方法。構造完成條件對象後,可以調用table對象的udpdate接口,完成更新操作,代碼如下。

1585275835790427.jpg

  ■刪除成績操作

  刪除操作和更新操作類似,需要調用table.remove接口完成,不再贅述,代碼如下。

1585275835849601.jpg

  ■查詢成績操作

  查詢成績操作很簡單,需要調用table.select接口完成,代碼如下。

1585275835919908.jpg

  至此基於CRUD的合約開發完成。

  從當前場景的代碼行數來看,CRUD合約比較複雜,Solidity合約相對簡單。但這只是一個幻覺,實際情況可能並非如此。而且CRUD合約的開發更符合開發者習慣,沒有多餘的學習成本,更容易理解和上手。

  4.合約部署及調用

  開發完智能合約後,需要對合約進行編譯和部署,然後才能調用。FISCO BCOS平臺提供了交互式控制檯工具(Console),可以非常方便地與鏈進行交互。下面將以上述智能合約爲例,採用控制檯工具進行部署和調用。

  控制檯安裝及使用可參考:

  https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/console.html。

  4.1準備工作

  在對合約進行部署和調用前需要做三件事情。首先複製編寫好的合約到控制檯目錄console/contracts/solidity下。如下圖所示。

1585275835989398.jpg

  其次對合約進行編譯,可以採用控制檯目錄下的sol2java.sh腳本對合約進行編譯,編譯結束後會在console/contracts/sdk目錄下生成如下文件夾,如下圖所示。

1585275836020172.jpg

  其中abi中存放合約的ABI,bin存放合約的二級制編碼文件(BINARY),JAVA文件夾中爲對應的JAVA合約,便於通過SDK和鏈進行交互。

  需要注意的是對CRUD合約編譯時。需要將CRUD接口合約Table.sol一併放入console/contracts/solidity目錄下,不然會報錯。

  最後,對合約進行部署時,依賴外部賬戶,所以首先需要生成賬戶。在控制檯中提供了賬戶生成工具get_account.sh,運行該腳本會在console/accounts目錄下生成賬戶。

  我們利用賬戶生成工具生成兩個賬戶。一個爲考試管理中心的賬戶,用於部署和新增/修改/刪除學生成績;一個爲學生賬戶,用於查看考試成績。如下所示。

1585275836061866.jpg

  4.2 Solidity合約部署和調用

  首先採用考試管理中心賬戶啓動控制檯,如下圖所示,即表示控制檯啓動成功。

1585275836116641.jpg

  然後通過deploy命令對合約進行部署,合約部署成功之後會返回合約地址,如下圖所示。

1585275836164510.jpg

  合約部署完成之後,可以通過控制檯的call命令調用合約函數。如下圖所示,新增學生的GRE成績爲70(修改和刪除均可通過調用setScore方法進行操作),函數返回值爲true,則表示交易成功。call命令的具體用法可以通過call -h 查看。

1585275836201840.jpg

  採用學生賬戶啓動控制檯,通過getScore函數查看成績,如下圖所示,返回值爲70,說明沒有問題。也可以使用學生賬戶調用setScore方法,會報錯,打印沒有權限,不再贅述。

1585275836243331.jpg

  4.3 CRUD合約部署和調用

  CRUD合約的部署和調用和Solidity合約沒有區別,這裏同樣採用控制檯進行。

  首先採用考試管理中心賬戶啓動控制檯,並對StudentScoreByCRUD合約進行部署。如下圖所示。

1585275836291117.jpg

  合約部署完成之後,調用create函數創建stu_score表,如下所示,返回結果爲0,說明創建成功。

1585275836352556.jpg

  創建好表之後,就可以調用相關接口對學生成績進行操作了,首先調用insert函數新增學生成績。如下所示,返回結果爲1,說明插入成績成功。

1585275836399121.jpg

  成績插入成功之後,關閉當前控制檯,用學生賬戶登錄控制檯,並調用select函數查詢成績,如下圖所示,返回70,說明查詢成功。剩餘函數測試可自行完成,不再贅述。

1585275836447491.jpg

  5.結束語

  本文重點介紹了FISCO BCOS平臺的智能合約開發。在FISCO BCOS平臺中,既可以採用原生Solidity語言開發智能合約,也可以使用預編譯合約模式開發合約。Solidity合約性能差、學習成本高;預編譯合約,採用預編譯引擎,支持並行計算,性能更高,同時支持存儲擴容等。

  但由於預編譯合約使用存在一定的門檻,基於此,FISCO BCOS平臺開發了CRUD合約接口,用戶不需要關心底層的實現邏輯,只需要引入Table.sol合約接口文件,通過調用相關接口即可完成合約的開發。

  關注“FISCO BCOS開源社區”公衆號,獲取更多智能合約實操內容


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章