中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

hyperledger fabric客戶端相關的開發有哪些

發布時間:2021-12-06 14:37:37 來源:億速云 閱讀:182 作者:小新 欄目:互聯網科技

這篇文章將為大家詳細講解有關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進行通訊。

SDK版本

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客戶端開發。

API作用

在 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 模塊

Node SDK由3個頂級模塊組成:

  • api : 可插拔式的API, 可自由定制, SDK提供默認實現

  • fabric-client :提供API用來同Hyperledger Fabirc的區塊鏈網絡進行交互, 具體就是同peer, orderer 和事件流交互。

  • fabric-ca-client:該API用來同fabirc提供的可選的CA實現Hyperledger Fabric CA交互, 該CA提供成員管理服務。

Node SDK 功能

fabric-client:

  • 創建一個新的通道(create channel)

  • 將通道信息發送給節點用于節點加入 (join channel)

  • 在節點上安裝鏈碼 (install chaincode)

  • 在通道中進行鏈碼實例化 (instantiate chaincode)

  • 提交交易, 包括 :提案和交易 (invoke)

  • 查詢鏈碼的最新狀態 (query)

  • 多種查詢功能

  1. 查詢通道長度

  2. 通過區塊高度查詢, 通過區塊hash查詢區塊

  3. 查詢一個節點所在的所有通道

  4. 查詢節點中安裝的所有鏈碼

  5. 查詢通道中的所有實例化鏈碼

  6. 通過tansaction ID查詢交易

  7. 查詢通道的配置數據

  • 監控事件

連接一個節點的事件流

監控一個區塊事件

監控交易事件和結果

堅挺鏈碼自定義事件

  • 序列化用戶對象和簽名功能

  • 多層覆蓋式的風層配置設置

  • 日志定義

  • 可插拔式的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客戶端相關的開發有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丰台区| 内黄县| 江源县| 崇礼县| 来安县| 常德市| 沈阳市| 广西| 新宁县| 吕梁市| 广平县| 惠水县| 十堰市| 临汾市| 邛崃市| 济南市| 长阳| 额尔古纳市| 巨野县| 平陆县| 兰考县| 长武县| 喀喇沁旗| 镇安县| 正蓝旗| 西充县| 克什克腾旗| 蒙山县| 孝昌县| 凌云县| 丰都县| 仁化县| 鄢陵县| 三江| 剑河县| 怀化市| 云阳县| 沂源县| 屯门区| 竹山县| 沧州市|