您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關hyperledger fabric客戶端相關的開發有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
hyperledger 的客戶端開發, 實際上指的是Chaincode的客戶端開發。
同傳統的互聯網開發一樣, 可以理解為hyperledger fabric是C/S架構, 當然這樣的類比不是很嚴謹。那么, 以前的服務端API在hyperledger fabric中相當于Chaincode開發, 以前的容器或者其他類似與Tomcat, Nginx 的服務器相當于 hyperledger 中的 Blockchain 本身, 當然在Blockchain中, 數據存儲也在Blockchain上, 所以Blochchain也是新的存儲平臺, 而傳統的客戶端開發, 其實就是通過SDK或者Restful APIs 和服務端進行交互, 在hyperledger中, 同樣可以使用SDK 或者 Restful APIs 來和服務端進行交互, 只是, 這個交互不僅僅適合自己定義的Chaincode中的業務邏輯來進行交互, 也和Chaincode本身進行交互, 在hyperledger中, 例如客戶端application 通過SDK連接訪問 peer, channel, orderer , Block, Transaction等。
總的來說, Hyperledger Fabric 客戶端開發主要包括通過Chaincode定義業務邏輯, 來改變Blockchain的狀態, 通過SDK來和Blockchain進行通訊。
Hyperledger Fabric 提供了多種語言的SDK版本, 目前主要包括:
官方支持的版本:
Hyperledger Fabric Node SDK
Hyperledger Fabric Java SDK
非官方的版本:
Hyperledger Fabric Python SDK
Hyperledger Fabric GO SDK
Hyperledger Fabric REST SDK
其中, 以 Hyperledger Fabric Node SDK的文檔最為詳細, 這里以Node SDK 為例來說明Hyperledger Fabric客戶端開發。
在 Hyperledger Fabric 的SDK中, 提供的API的作用主要有:
創建通道 (create channel)
請求節點加入通道 (join channel)
在節點中安裝鏈碼 (install chaincode)
通過調用鏈碼來調用事物 (invoke chaincode)
查詢事物或者區塊的賬本 (query chaincode)
在 交易流程 中提供了一個應用程序(SDK), peer 和 orderer 共同處理事物并產生區塊的流程。Fabric的安全是通過數字簽名來實現的, 在Fabric中所有的請求都必須具有有效注冊證書的用戶簽名。對于在Fabric中被認為有效的證書, 必須具有受信任的證書頒發機構簽名。Fabirc支持CA的所有標準, Fabric 同時提供了一個可選的CA實現。
Node SDK由3個頂級模塊組成:
api : 可插拔式的API, 可自由定制, SDK提供默認實現
fabric-client :提供API用來同Hyperledger Fabirc的區塊鏈網絡進行交互, 具體就是同peer, orderer 和事件流交互。
fabric-ca-client:該API用來同fabirc提供的可選的CA實現Hyperledger Fabric CA交互, 該CA提供成員管理服務。
fabric-client:
創建一個新的通道(create channel)
將通道信息發送給節點用于節點加入 (join channel)
在節點上安裝鏈碼 (install chaincode)
在通道中進行鏈碼實例化 (instantiate chaincode)
提交交易, 包括 :提案和交易 (invoke)
查詢鏈碼的最新狀態 (query)
多種查詢功能
查詢通道長度
通過區塊高度查詢, 通過區塊hash查詢區塊
查詢一個節點所在的所有通道
查詢節點中安裝的所有鏈碼
查詢通道中的所有實例化鏈碼
通過tansaction ID查詢交易
查詢通道的配置數據
監控事件
連接一個節點的事件流
監控一個區塊事件
監控交易事件和結果
堅挺鏈碼自定義事件
序列化用戶對象和簽名功能
多層覆蓋式的風層配置設置
日志定義
可插拔式的CryptoSuite
可插拔式的狀態存儲
自定義的密鑰存儲
支持TLS和非TLS連接到peer 和orderer
fabric-ca-client:
注冊新用戶 (register)
登記用戶同時獲取有Fabric CA簽署的注冊證書(enroll)
通過注冊ID廢除已有用戶或廢除特定證書 (revoke)
自定義的持久化存儲
下面通過一個實例來說明Hyperledger Fabric客戶端開發。一下是一段Chaincode, 定義了業務邏輯。
【有點類似傳統的管理系統開發, chaincode實現CURD的功能, 通過SDK與fabric 交互, 來達到Blockchain狀態的改變, 只是, chaincode支持byte和json數據,并且是以KV的形式存儲】
/* # Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 */ 'use strict'; const shim = require('fabric-shim'); const util = require('util'); let Chaincode = class { // The Init method is called when the Smart Contract 'fabcar' is instantiated by the blockchain network // Best practice is to have any Ledger initialization in separate function -- see initLedger() async Init(stub) { console.info('=========== Instantiated fabcar chaincode ==========='); return shim.success(); } // The Invoke method is called as a result of an application request to run the Smart Contract // 'fabcar'. The calling application program has also specified the particular smart contract // function to be called, with arguments async Invoke(stub) { let ret = stub.getFunctionAndParameters(); console.info(ret); let method = this[ret.fcn]; if (!method) { console.error('no function of name:' + ret.fcn + ' found'); throw new Error('Received unknown function ' + ret.fcn + ' invocation'); } try { let payload = await method(stub, ret.params); return shim.success(payload); } catch (err) { console.log(err); return shim.error(err); } } async queryCar(stub, args) { if (args.length != 1) { throw new Error('Incorrect number of arguments. Expecting CarNumber ex: CAR01'); } let carNumber = args[0]; let carAsBytes = await stub.getState(carNumber); //get the car from chaincode state if (!carAsBytes || carAsBytes.toString().length <= 0) { throw new Error(carNumber + ' does not exist: '); } console.log(carAsBytes.toString()); return carAsBytes; } async initLedger(stub, args) { console.info('============= START : Initialize Ledger ==========='); let cars = []; cars.push({ make: 'Toyota', model: 'Prius', color: 'blue', owner: 'Tomoko' }); cars.push({ make: 'Ford', model: 'Mustang', color: 'red', owner: 'Brad' }); cars.push({ make: 'Hyundai', model: 'Tucson', color: 'green', owner: 'Jin Soo' }); cars.push({ make: 'Volkswagen', model: 'Passat', color: 'yellow', owner: 'Max' }); cars.push({ make: 'Tesla', model: 'S', color: 'black', owner: 'Adriana' }); cars.push({ make: 'Peugeot', model: '205', color: 'purple', owner: 'Michel' }); cars.push({ make: 'Chery', model: 'S22L', color: 'white', owner: 'Aarav' }); cars.push({ make: 'Fiat', model: 'Punto', color: 'violet', owner: 'Pari' }); cars.push({ make: 'Tata', model: 'Nano', color: 'indigo', owner: 'Valeria' }); cars.push({ make: 'Holden', model: 'Barina', color: 'brown', owner: 'Shotaro' }); for (let i = 0; i < cars.length; i++) { cars[i].docType = 'car'; await stub.putState('CAR' + i, Buffer.from(JSON.stringify(cars[i]))); console.info('Added <--> ', cars[i]); } console.info('============= END : Initialize Ledger ==========='); } async createCar(stub, args) { console.info('============= START : Create Car ==========='); if (args.length != 5) { throw new Error('Incorrect number of arguments. Expecting 5'); } var car = { docType: 'car', make: args[1], model: args[2], color: args[3], owner: args[4] }; await stub.putState(args[0], Buffer.from(JSON.stringify(car))); console.info('============= END : Create Car ==========='); } async queryAllCars(stub, args) { let startKey = 'CAR0'; let endKey = 'CAR999'; let iterator = await stub.getStateByRange(startKey, endKey); let allResults = []; while (true) { let res = await iterator.next(); if (res.value && res.value.value.toString()) { let jsonRes = {}; console.log(res.value.value.toString('utf8')); jsonRes.Key = res.value.key; try { jsonRes.Record = JSON.parse(res.value.value.toString('utf8')); } catch (err) { console.log(err); jsonRes.Record = res.value.value.toString('utf8'); } allResults.push(jsonRes); } if (res.done) { console.log('end of data'); await iterator.close(); console.info(allResults); return Buffer.from(JSON.stringify(allResults)); } } } async changeCarOwner(stub, args) { console.info('============= START : changeCarOwner ==========='); if (args.length != 2) { throw new Error('Incorrect number of arguments. Expecting 2'); } let carAsBytes = await stub.getState(args[0]); let car = JSON.parse(carAsBytes); car.owner = args[1]; await stub.putState(args[0], Buffer.from(JSON.stringify(car))); console.info('============= END : changeCarOwner ==========='); } }; shim.start(new Chaincode());
關于“hyperledger fabric客戶端相關的開發有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。