總目錄:
(0) 如何利用區塊鏈保護知識產權
(一)HyperLedger Fabric 2.0-release測試網絡部署
(二)Fabric2.0 first-network 生成配置說明
(三)Fabric2.0啓動網絡腳本配置剖析
(四)Fabric2.0通道實踐
(五)Fabric2.0 智能合約實踐- 安裝以及定義智能合約
(六)Fabric2.0 智能合約實踐- 升級智能合約
(七)Fabric2.0智能合約實踐-設置背書策略
(八)Fabric2.0Java SDK實踐-合約交易
(九)Fabric2.0 通道實踐-更新通道配置
(十)Fabric2.0-動態添加組織
(十一) Fabric2.0-使用編輯器調試go智能合約
(十二)Fabric2.0-實現外部構建啓動合約
工具人大膽試探raft共識-你沒見過的raft算法解釋
目錄
根據前面的步驟,我們基於cli客戶端完成了一系列操作,但是正常情況下,我們的工程一般會使用SDK去調用
網絡完成交易,因此從這一章開始實踐何基於Java SDK調用Fabric2.0網絡完成交易。
1.Gateway
在進行實踐前,有一個比較新的概念需要了解就是Gateway。
爲了應對由於Fabric網絡中的變化頻繁所造成的後果,Fabric2.0 原本的SDK之上蓋了一層網關Gateway,用於減輕應用程序的負擔。
具體拓撲結構如下:
MagnetoCorp和DigiBank應用程序(發行和購買)將各自的網絡交互委託給其網關。每個網關都瞭解網絡通道拓撲,其中包括兩個組織MagnetoCorp和DigiBank的多個peers和order,使應用程序專注於業務邏輯。節點間可以使用gossip協議在組織內部和組織之間相互共識交互。
2.環境準備
系統工具 | 版本 | 備註 |
---|---|---|
Window | 10 | |
Fabric | 2.0 | 已部署好mychannel通道以及mycc合約到兩個組織節點 |
Java | 1.8 | |
Maven | 3.5.2 |
Fabric網絡結構
節點類型 | 節點名 | 所屬組織 | ip | 服務端口 |
---|---|---|---|---|
orderer | orderer.example.com | - | 192.168.2.104 | 7050 |
peer | peer0.org1.example.com | org1 | 192.168.2.104 | 7051 |
peer | peer1.org1.example.com | org1 | 192.168.2.104 | 8051 |
peer | peer0.org2.example.com | org2 | 192.168.2.104 | 9051 |
peer | peer1org2.example.com | org2 | 192.168.2.104 | 10051 |
ca | ca1.org1.example.com | org1 | 192.168.2.104 | 7054 |
ca | ca2.org1.example.com | org2 | 192.168.2.104 | 8054 |
3.創建基礎工程
新建一個Maven工程,添加以下依賴:
<dependency>
<groupId>org.hyperledger.fabric</groupId>
<artifactId>fabric-gateway-java</artifactId>
<version>2.0.0</version>
</dependency>
4.創建connectionProfile
connectionProfile用於創建一個連接網絡對象,如果有跑過first-network的朋友,相比記得一個ccp.sh的命令,生成的connection-org1.json、connection-org1.yaml這種文件,其實這些就是我們所需要的connectionProfile,可以直接使用。當然也可以自行編寫,自行編寫請參考官方模板
4.1 配置文件結構說明
整體connectionProfile結構如下
包含對象說明:
參數名 | 描述 |
---|---|
name | 自定義網絡名稱 |
version | 自定義網絡版本 |
client | 客戶端相關信息 |
channels | 網絡所包含的通道信息 |
organizations | 網絡中組織信息 |
orderers | 排序節點信息 |
peer | pee節點信息 |
certificateAuthorities | ca節點信息 |
4.1.1 client
4.1.2 channels
其中節點對象有4中角色定義
角色 | 描述 |
---|---|
endorsingPeer | 具有背書權限節點 |
chaincodeQuery | 具有合約查詢權限節點 |
ledgerQuery | 具有賬本查詢權限節點 |
eventSource | event hub節點 |
4.1.3 organizations
其中admin私鑰與admin簽名證書支持路徑與文件內容,路徑使用參數path
,對應值填寫路徑,文件內容使用參數pem
,對應值填寫私鑰或者證書內容。
4.1.4 orderers
4.1.5 peer
與排序節點類似,如果是tls必須配置tlsCACerts
4.1.6 certificateAuthorities
與排序節點類似,如果是tls必須配置tlsCACerts
5. JAVA工程目錄說明
新建的工程目錄如下
src/main/java : 存放demo主程序類
src/main/resources/connection.json : 上面新建好的connectionProfile
src/main/resources/crypto-config: 存放fabric網絡證書內容(選擇用到的就行)
6. 實踐
6.1 創建網關賬戶
網關賬戶就是相當於連接fabric網絡的fabric用戶對象。
//使用org1中的user1初始化一個網關wallet賬戶用於連接網絡
Wallet wallet = Wallets.newInMemoryWallet();
Path certificatePath = credentialPath.resolve(Paths.get("signcerts", "[email protected]"));
certificate = readX509Certificate(certificatePath);
Path privateKeyPath = credentialPath.resolve(Paths.get("keystore", "priv_sk"));
privateKey = getPrivateKey(privateKeyPath);
//放進wallet
wallet.put("user",Identities.newX509Identity("Org1MSP",certificate,privateKey));
賬戶對象都可以存放到wallet裏面,方便存取。
證書對象使用的是org1的user私鑰,證書。
6.2 創建網關
通過connectionProfile以及網關賬戶創建網關
//根據connection-org1.json 獲取Fabric網絡連接對象
GatewayImpl.Builder builder = (GatewayImpl.Builder) Gateway.createBuilder();
builder.identity(wallet, "user").networkConfig(NETWORK_CONFIG_PATH);
NETWORK_CONFIG_PATH : connectionProfile文件路徑
6.3 連接網關
//連接網關
gateway = builder.connect();
//獲取mychannel通道
Network network = gateway.getNetwork("mychannel");
//獲取合約對象
Contract contract = network.getContract("mycc");
網關連接後
getNetwork
:可以根據通道名稱獲取Fabric具體通道網絡
network.getContract
:可以根據合約名稱獲取部署到對應通道的智能合約對象
6.4 交易
基於上一部分的智能合約,有一個addTen的交易,結果是對象加10
首先我們對合約對象a
當前的值進行查詢
//查詢合約對象evaluateTransaction
byte[] queryAResultBefore = contract.evaluateTransaction("query","a");
System.out.println("交易前:"+new String(queryAResultBefore, StandardCharsets.UTF_8));
然後調用addTen
進行a+10
// 創建並且提交交易
byte[] invokeResult = contract.createTransaction("addTen")
.setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))
.submit("a");
System.out.println(new String(invokeResult, StandardCharsets.UTF_8));
此處setEndorsingPeers
設置背書節點,這裏選擇了通道中背書權限節點集合
交易完成後再次進行查詢
//查詢合約對象evaluateTransaction
byte[] queryAResultAfter = contract.evaluateTransaction("query","a");
System.out.println("交易後:"+new String(queryAResultAfter, StandardCharsets.UTF_8));
最後控制檯輸出:
交易成功。
7. 總結
在調用交易方面,通過網關這種確實簡單了很多,後面應用程序進行設計的時候,可以將網關這個包單獨封裝,應用程序再進行調用,可以基於網關這層保障應用程序的業務穩定性。而再創建通道、加入通道、部署合約等操作應該還是SDK那套,後續章節也將繼續實踐。需要本章源碼的可以評論留言。
源碼:https://github.com/llzz9595/fabricdemo