預編譯合約極速開發指南(附完整步驟+實操模板)

因預編譯合約的使用方式與普通Solidity合約使用方式完全相同,該框架能做到在不改變客戶端開發者體驗的情況下,獲得極高的運行速度,這對邏輯相對確定、追求高速度和併發能力的場景來說,可謂是屠龍刀一樣的存在。

今天,我將以HelloWorld合約爲例,爲大家介紹如何使用預編譯合約版本的HelloWorld。注意,本章內容需要你具備一定的C++開發經驗,且詳細閱讀了《FISCO BCOS 2.0原理解析: 分佈式存儲架構設計》

下圖所示5個步驟是開發預編譯合約的必經之路,我將按步驟實現HelloWorld預編譯合約,然後分別使用控制檯、Solidity合約兩種方式來調用HelloWorld預編譯合約。

 

HelloWorld預編譯合約開發

 

先來看一下我們想要實現的HelloWorld合約的Solidity版本。Solidity版本的HelloWorld,有一個成員name用於存儲數據,兩個接口get(),set(string)分別用於讀取和設置該成員變量。

 

#step1#

定義HelloWorld接口

Solidity的接口調用都會被封裝爲一筆交易,其中,調用只讀接口的交易不會被打包進區塊,而寫接口交易會被打包進區塊中。由於底層需要根據交易數據中的ABI編碼來判斷調用的接口並解析參數,所以需要先把接口定義出來。

預編譯合約的ABI接口規則與Solidity完全相同,定義預編譯合約接口時,通常需要定義一個有相同接口的Solidity合約,這個合約稱爲預編譯合約的接口合約。接口合約在調用預編譯合約時需要使用。

 

#step2#

設計存儲結構

預編譯合約涉及存儲操作時,需要確定存儲的表信息(表名與表結構,存儲數據在FISCO BCOS中會統一抽象爲表結構)。這在之前的文章分佈式存儲架構設計有介紹。如果合約中不涉及變量存儲,可以忽略該步驟。

對於HelloWorld,我們設計如下的表。該表只存儲一對鍵值對,key字段爲hello_key,value字段爲hello_value 存儲對應的字符串值,可以通過set(string)接口修改,通過get()接口獲取。

 

#step3#

實現合約邏輯

實現新增合約的調用邏輯,需要新實現一個C++類,該類需要繼承Precompiled類, 重載call函數, 在call函數中實現各個接口的調用行爲。

call函數有三個參數,_context保存交易執行的上下文,_param是調用合約的參數信息,本次調用對應合約接口以及接口的參數可以從_param解析獲取,_origin是交易發送者,用於權限控制。

接下來,我們在源碼FISCO-BCOS/libprecompiled/extension目錄下實現HelloWorldPrecompiled類,重載call函數,實現get()/set(string)兩個接口。

 

接口註冊:

 

創建表:

在call函數中添加打開表的邏輯

 

區分調用接口:

 

參數解析與返回:

調用合約時的參數包含在call函數的_param參數中,是按照Solidity ABI格式進行編碼,使用dev::eth::ContractABI工具類可以進行參數的解析,同樣接口返回時返回值也需要按照該編碼格編碼。

dev::eth::ContractABI類中我們需要使用abiIn/abiOut兩個接口,前者用戶參數的序列化,後者可以從序列化的數據中解析參數。

 

HelloWorldPrecompiled實現:

考慮手機上的閱讀體驗,我們分塊介紹call接口內部實現並省略部分錯誤處理邏輯,詳細代碼實現可以參考FISCO BCOS 2.0文檔使用手冊->智能合約開發->預編譯合約開發。可複製下列鏈接到網頁中查看:

https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/smart_contract.html#id2

get()接口實現

set接口實現

 

#step4#

分配並註冊合約地址

FSICO BCOS 2.0執行交易時,根據合約地址區分是不是預編譯合約,所以開發完預編譯合約後,需要在底層註冊爲預編譯合約註冊地址。2.0版本地址空間劃分如下:

用戶分配地址空間爲0x5001-0xffff,用戶需要爲新添加的預編譯合約分配一個未使用的地址,預編譯合約地址必須唯一, 不可衝突

開發者需要修改
FISCO-BCOS/cmake/templates/UserPrecompiled.h.in文件,在registerUserPrecompiled函數中註冊HelloWorldPrecompiled合約的地址(要求v2.0.0-rc2以上版本),如下注冊HelloWorldPrecompiled合約:

 

#step5#

編譯源碼

參考FISCO BCOS 2.0使用手冊->獲取可執行程序->源碼編譯。

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

需要注意的是,實現的

HelloWorldPrecompiled.cpp

和HelloWorldPrecompiled.h

需要放置於

FISCO-BCOS/libprecompiled/extension目錄下。

 

HelloWorld預編譯合約調用

 

使用控制檯調用HelloWorld預編譯合約

在控制檯solidity/contracts創建HelloWorldPrecompiled.sol文件,文件內容是HelloWorld預編譯合約的接口聲明,如下

pragma solidity ^0.4.24;

contract HelloWorldPrecompiled{

function get() public constant returns(string);

function set(string n);

}

使用編譯出的二進制搭建節點後,部署控制檯v1.0.2以上版本,然後執行下面語句即可調用

 

在Solidity中調用HelloWorld預編譯合約

我們嘗試在Solidity合約中創建預編譯合約對象並調用其接口。在控制檯solidity/contracts創建HelloWorldHelper.sol文件,文件內容如下

pragma solidity ^0.4.24;

import "./HelloWorldPrecompiled.sol";

contract HelloWorldHelper {

HelloWorldPrecompiled hello;

function HelloWorldHelper() {

// 調用HelloWorld預編譯合約

hello = HelloWorldPrecompiled(0x5001);

}

function get() public constant returns(string) {

return hello.get();

}

function set(string m) {

hello.set(m);

}

}

 

部署HelloWorldHelper合約,然後調用HelloWorldHelper合約的接口,結果如下

到這裏,就可以恭喜你順滑地完成了HelloWorld預編譯合約的開發,其他預編譯合約的開發流程道理相通。

 


 

我們鼓勵機構成員、開發者等社區夥伴參與開源共建事業,有你在一起,會更了不起。多樣參與方式:

1 進入微信社羣,隨時隨地與圈內最活躍、最頂尖的團隊暢聊技術話題(進羣請添加小助手微信,微信ID:fiscobcosfan);

2 訂閱我們的公衆號:“FISCO BCOS開源社區”,我們爲你準備了開發資料庫、最新FISCO BCOS動態、活動、大賽等信息;

3 來Meetup與開發團隊面對面交流,FISCO BCOS正在全國舉辦巡迴Meetup,深圳、北京、上海、成都……歡迎您公衆號在菜單欄【找活動】中找到附近的Meetup,前往結識技術大咖,暢聊硬核技術;

4 參與代碼貢獻,您可以在Github提交Issue進行問題交流,歡迎向FISCO BCOS提交Pull Request,包括但不限於文檔修改、修復發現的bug、提交新的功能特性。

代碼貢獻指引:

https://github.com/FISCO-BCOS/FISCO-BCOS/blob/master/docs/CONTRIBUTING_CN.md

 

本文首發於公衆號【FISCO BCOS開源社區】,如轉載請註明出處,原創不易,謝謝珍惜

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