Hyperledger Fabric V1.4Javascript链码开发常用API

Posted 一朵小奇葩✿ۣ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hyperledger Fabric V1.4Javascript链码开发常用API相关的知识,希望对你有一定的参考价值。

Ⅰ ChaincodeStub类封装了链码和peer节点之间交互的APIs,使用方式为ctx.stub.method(),js合约文件如下:

const { Contract } = require(‘fabric-contract-api‘);   //引入依赖

class ElecDataContract extends Contract {   //ElecDataContract 为自定义的合约类

  async elecDataExists(ctx, elecDataId) {   //自定义事务,查询由elecDataId标识的电子数据是否已存在
    const buffer = await ctx.stub.getState(elecDataId);   //调用ctx.stub.getState()方法
    return (!!buffer && buffer.length > 0);
  }

}

Ⅱ 常用API:

① <async> getState(key)   //参数类型string,返回类型buffer

功能:检索状态数据库中键的当前值

② <async> putState(key, value)   //参数类型string,buffer或string

功能:向状态数据库写入新的键值对,如果变量已经存在,则该值将被覆盖

③ <async>deleteState(key)   //参数类型string

功能:根据key从状态数据库中删除键值对

④ <async> getStateByRange(startKey, endKey)   //参数类型string,string,返回类型StateQueryIterator迭代器(迭代访问后需要调用其close()函数)

功能:在账本中的一组键上返回一个范围迭代器。迭代器可用于迭代startKey(包含)和endKey(排除)之间的所有键。startKey和endKey可以是空字符串,这意味着开始或结束的查询范围是不受限制的

⑤ <async> getHistoryForKey(key)   //参数类型string,返回类型HistoryQueryIterator迭代器

功能:返回键值随时间变化的历史记录。对于每个历史键更新,将返回历史值和关联的事务id和时间戳

⑥ createCompositeKey(objectType, attributes)   //参数类型string,string数组,返回类型string

功能:通过组合objectType字符串和给定的“属性”来创建组合键,objectType和属性应该是有效的utf8字符串,得到的组合键可以用作putState()中的键

解析:Hyperledger Fabric使用一个简单的键/值模型来保存链码状态。在某些用例场景中,有必要跟踪多个属性。此外,可能需要使各种属性可搜索。可以使用组合键来满足这些需求。类似于在关系数据库表中使用组合键,这里可以将可搜索属性视为组成组合键的键列。属性的值成为键的一部分,因此可以通过getStateByRange()和getStateByPartialCompositeKey()等函数来搜索它们

示例(创建资产的事务):

marbleName = ‘marble1’

let marble = {   //构造一个marble对象

       name: marbleName,

    color: ‘blue’,

       owner: ‘wang’,

    size: 50

};

 //首先将marble对象添加到由marbleName标识的状态数据库

await stub.putState(marbleName, Buffer.from(JSON.stringify(marble)));  

//然后生成color和owner的组合键,以支持基于这些属性的范围查询,如返回所有蓝色marble

let indexName = ‘color~name‘;

let colorNameIndexKey = await stub.createCompositeKey(indexName, [marble.color, marble.name]);

//将组合键保存到状态数据库,组合键作为key,而value在此置为null(nil)(value为空时,删除效率高)

await stub.putState(colorNameIndexKey, Buffer.from(‘u0000‘));

注:删除状态数据库中某个键值对时,除了调用deleteState(marbleName)函数删除marble,同样需要删除marble对应的组合键

let indexName = ‘color~name‘;

let colorNameIndexKey = await stub.createCompositeKey(indexName, [marble.color, marble.name]);

await stub.deleteState(colorNameIndexKey);

⑦ <async> getStateByPartialCompositeKey(objectType, attributes)   //参数类型string,string数组,返回类型StateQueryIterator迭代器(迭代访问后需要调用其close()函数)

功能:根据给定的部分组合键查询分类账中的状态。

示例:查询color为blue的所有marble

let coloredMarbleResultsIterator = await stub.getStateByPartialCompositeKey(‘color~name‘, [“blue”]);

⑧ splitCompositeKey(compositeKey)   //参数类型string,返回类型是一个对象,该对象包括两个属性,objectType与attributes,objectType为string,attributes为字符数组

功能:将组合键拆分为组成复合键的属性。在范围查询或部分组合键查询中得到的组合键可以被分割成它们原来的组合部分,该函数本质上是恢复属性的值。

示例:

//查询所有color为‘blue’的marble,查到的结果为符合键作为键的键值对(value为空值),而不是以marbleName为标识的那些键值对,因此需要从符合键中拆分出marbleName属性,并通过getState(marbleName)获得符合最初查询条件的marble对象,并进行后续其他处理。

let coloredMarbleResultsIterator = await stub.getStateByPartialCompositeKey(‘color~name‘, [“blue”]);

//迭代

while (true) {

      let responseRange = await coloredMarbleResultsIterator.next();   //迭代器元素的value属性为键值对,responseRange.value.key为组合键

     let objectType;

     let attributes;

     ({            //拆解组合键

        objectType,

        attributes

     } = await stub.splitCompositeKey(responseRange.value.key));

     let returnedColor = attributes[0];  

     let returnedMarbleName = attributes[1];   //然后可通过getState(marbleName)获得符合最初查询条件的marble对象,并进行后续其他处理。

}

⑨ <async> getQueryResult(query)   //参数类型string,返回类型StateQueryIterator迭代器

功能:执行“富”查询。query为底层状态数据库(Couchdb)的本地查询字符串(json格式)

示例:查询指定owner的所有marble

let queryString = {};

    queryString.selector = {};

    queryString.selector.owner = owner;

let resultsIterator = await stub.getQueryResult(JSON.stringify(queryString));

⑩ 其他

getChannelID()    //返回chaincode要处理的事务的通道ID

getCreator ()   //返回chaincode调用提交者的标识对象

getTxID()   //返回当前chaincode调用请求的事务ID。事务ID惟一地标识通道范围内的事务。

getTxTimestamp()   //返回创建事务时的时间戳(客户端发起请求的时间)。

注:未提到的函数包括对私有数据的操作(所有的get及put均有面向私有数据的函数)以及分页操作(所有的get查询均有对应的分页查询)

Ⅲ 由于存在多个查询(get)函数返回结果为迭代器,因此需要一个自定义函数对迭代器中的查询结果进行遍历:

async getAllResults(iterator, isHistory) {

    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‘));

        if (isHistory && isHistory === true) {

          jsonRes.TxId = res.value.tx_id;

          jsonRes.Timestamp = res.value.timestamp;

          jsonRes.IsDelete = res.value.is_delete.toString();

          try {

            jsonRes.Value = JSON.parse(res.value.value.toString(‘utf8‘));

          } catch (err) {

            console.log(err);

            jsonRes.Value = res.value.value.toString(‘utf8‘);

          }

        } else {

          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 allResults;

      }

    }

  }

功能:迭代器函数,可以迭代由getStateByRange(startKey, endKey)、getQueryResult(query)、getHistoryForKey(key)返回的迭代器获得其中元素的值。由于键值历史查询的内容与常规状态查询的内容不同,因此根据是否查询键值历史,调用该方法的方式为getAllResults(iterator, true)或getAllResults(iterator, false)。

注:getStateByPartialCompositeKey(objectType, attributes)获得的迭代器使用splitCompositeKey(compositeKey)另作处理,因为查询到的键值对的key为组合键,值为空,我们需要恢复组合键的属性做其他后续处理。该函数主要用于范围查询与处理。

 

以上是关于Hyperledger Fabric V1.4Javascript链码开发常用API的主要内容,如果未能解决你的问题,请参考以下文章

Fabric系列 - Hyperledger开源项目介绍

Fabric系列 - Hyperledger开源项目介绍

hyperledger fabric backup

Hyperledger Fabric 1.1安装部署-Fabric Samples

Hyperledger-fabric 环境搭建

搭建基于hyperledger fabric的联盟社区 --启动Fabric网络