hyperledger fabric客户端相关的开发有哪些

发布时间:2021-12-06 14:37:37 作者:小新
来源:亿速云 阅读:178

这篇文章将为大家详细讲解有关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的文档最为详细, 这里以Node SDK 为例来说明Hyperledger Fabric客户端开发。

API作用

在 Hyperledger Fabric 的SDK中, 提供的API的作用主要有:

在 交易流程 中提供了一个应用程序(SDK), peer 和 orderer 共同处理事物并产生区块的流程。Fabric的安全是通过数字签名来实现的, 在Fabric中所有的请求都必须具有有效注册证书的用户签名。对于在Fabric中被认为有效的证书, 必须具有受信任的证书颁发机构签名。Fabirc支持CA的所有标准, Fabric 同时提供了一个可选的CA实现。

Node SDK 模块

Node SDK由3个顶级模块组成:

Node SDK 功能

fabric-client:

  1. 查询通道长度

  2. 通过区块高度查询, 通过区块hash查询区块

  3. 查询一个节点所在的所有通道

  4. 查询节点中安装的所有链码

  5. 查询通道中的所有实例化链码

  6. 通过tansaction ID查询交易

  7. 查询通道的配置数据

连接一个节点的事件流

监控一个区块事件

监控交易事件和结果

坚挺链码自定义事件

fabric-ca-client:

实例

下面通过一个实例来说明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客户端相关的开发有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

推荐阅读:
  1. Hyperledger Fabric注册及CA证书颁发
  2. HyperLedger Fabric 交易流程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

hyperledger fabric hyperledger fabric

上一篇:HBase如何解决Region Server Compact过程占用大量网络出口带宽的问题

下一篇:怎样解决在openstack中通过wget无法进行下载的问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》