balance transfer 提供了很多查询接口,包括链码查询,根据区块号查询区块数据,根据交易ID查询交易信息,查询链上的区块数,查询已安装或已实例化的链码,查询通道。

源码解析

1.调用链码查询:调用指定背书节点上部署的普通chaincode对状态数据库进行查询操作,该方法只会发送交易提案到目标节点,并不会产生新的交易发送给排序服务。

// 调用指定节点上部署的普通链码进行查询
app.get('/channels/:channelName/chaincodes/:chaincodeName', async function(req, res) {
var channelName = req.params.channelName;
var chaincodeName = req.params.chaincodeName;
let args = req.query.args;
let fcn = req.query.fcn;
let peer = req.query.peer;
// 处理参数
args = args.replace(/'/g, '"');
args = JSON.parse(args);
logger.debug(args); let message = await query.queryChaincode(peer, channelName, chaincodeName, args, fcn, req.username, req.orgname);
res.send(message);
}); // query.js中的queryChaincode()方法
var queryChaincode = async function(peer, channelName, chaincodeName, args, fcn, username, org_name) {
try {
// 创建client和channel对象
var client = await helper.getClientForOrg(org_name, username);
var channel = client.getChannel(channelName); // 构造查询请求
var request = {
targets : [peer], // 允许指定多个节点
chaincodeId: chaincodeName,
fcn: fcn,
args: args
};
// 调用SDK中的queryByChaincode()方法,内部调用sendTransactionProposal()
// 向所有目标背书节点发送生成的交易提案,并提取出所有提案响应中的payload组成一个list返回
let response_payloads = await channel.queryByChaincode(request); // 从响应内容中解析出查询结果, response_payloads是一个list类型
// 其中每个元素都是一个字节数组(bytes array),对应每一个指定节点的查询结果
if (response_payloads) {
for (let i = 0; i < response_payloads.length; i++) {
logger.info(args[0]+' now has ' + response_payloads[i].toString('utf8') +
' after the move');
}
return args[0]+' now has ' + response_payloads[0].toString('utf8') +
' after the move';
} else {
logger.error('response_payloads is null');
return 'response_payloads is null';
}
} catch(error) {
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
return error.toString();
}
};

2.根据区块号查询区块数据

app.get('/channels/:channelName/blocks/:blockId', async function(req, res) {
let blockId = req.params.blockId;
let peer = req.query.peer; let message = await query.getBlockByNumber(peer, req.params.channelName, blockId, req.username, req.orgname);
res.send(message);
}); var getBlockByNumber = async function(peer, channelName, blockNumber, username, org_name) {
try {
// 创建client和channel对象
var client = await helper.getClientForOrg(org_name, username);
var channel = client.getChannel(channelName); // 调用SDK中的queryBlock方法,内部调用sendTransactionProposal()发送交易提案到背书节点,
// 背书节点会调用 QSCC 系统链码中的 GetBlockByNumber 接口从链上获取区块数据
let response_payload = await channel.queryBlock(parseInt(blockNumber, peer));
if (response_payload) {
logger.debug(response_payload);
return response_payload;
} else {
logger.error('response_payload is null');
return 'response_payload is null';
}
} catch(error) {
logger.error('Failed to query due to error: ' + error.stack ? error.stack : error);
return error.toString();
}
};

总结

其他的查询方法与上面查询区块的方法类似,都是先调用query.js的对应接口,再调用SDK中的对应接口,然后内部调用 sendTransactionProposal()来发送交易提案到背书节点,随后背书节点调用相应系统链码中的对应方法来进行查询。

查询功能 app调用 SDK调用 链码调用 链码方法fcn
链码查询 queryChaincode queryByChaincode chaincode query
根据区块号获取区块 getBlockByNumber queryBlock QSCC GetBlockByNumber
根据交易号获取交易 getTransactionByID queryTransaction QSCC GetTransactionByID
根据区块hash获取区块 getBlockByHash queryBlockByHash QSCC GetBlockByHash
查询链信息 getChainInfo queryInfo QSCC GetChainInfo
查询已安装链码 getInstalledChaincodes queryInstalledChaincodes LSCC getinstalledchaincodes
查询已实例化链码 getInstalledChaincodes queryInstantiatedChaincodes LSCC getchaincodes
查询链信息 getChainInfo queryInfo QSCC GetChainInfo
查询加入的通道 getChannels queryChannels CSCC GetChannels

Hyperledger Fabric——balance transfer(六)查询的更多相关文章

  1. Hyperledger Fabric——balance transfer(一)启动示例

    Blacne transfer是Hyperledger fabric Node SDK的一个示例应用,主要使用了SDK中fabric-client 和 fabric-ca-client 模块中的API ...

  2. Hyperledger Fabric——balance transfer(四)安装和实例化chaincode

    详细解析blance transfer示例的安装(install)和实例化(Instantiate)链码(chaincode)的过程.安装chaincode会根据本地的链码文件生成chaincode镜 ...

  3. Hyperledger Fabric——balance transfer(三)创建和加入Channel

    详细解析blance transfer示例的创建通道(Channel)和加入节点到通道的过程. 创建Channel 1.首先看app.js的路由函数 var createChannel = requi ...

  4. Hyperledger Fabric——balance transfer(二)注册用户

    详细分析blance transfer示例的用户注册(register)与登录(enroll)功能. 源码分析 1.首先分析项目根目录的app.js文件中关于用户注册和登录的路由函数.注意这里的tok ...

  5. Hyperledger Fabric——balance transfer(五)执行交易

    链码安装和实例化之后就可以调用chaincode执行交易,下面分析简单的账户转账操作是如何完成的. 源码分析 1.首先看app.js的路由函数 app.post('/channels/:channel ...

  6. 搭建基于hyperledger fabric的联盟社区(六) --搭建node.js服务器

    接下来我要做的是用fabric sdk来做出应用程序,代替CLI与整个区块链网络交互.并且实现一个http API,向社区提供一个简单的接口,使社区轻松的与区块链交互. 官方虽然提供了Node.JS, ...

  7. Hyperledger Fabric 1.0 从零开始(六)——创建Fabric多节点集群

    4:创建Fabric多节点集群 4.1.配置说明 首先可以根据官方Fabric自带的e2e_cli列子中的集群方案来生成我们自己的集群,与案例不同的是我们需要把容器都分配到不同的服务器上,彼此之间通过 ...

  8. hyperledger fabric 1.0.5 分布式部署 (六)

    如何在相同的peer 节点上创建多个 channel 作者在hyperledger fabric 1.0.5 分布式部署 (五)已经向读者们介绍了一个简单的fabric 的部署流程,那么根据上一篇博客 ...

  9. Hyperledger Fabric 2.x 自定义智能合约

    一.说明 为了持续地进行信息的更新,以及对账本进行管理(写入交易,进行查询等),区块链网络引入了智能合约来实现对账本的访问和控制:智能合约在 Fabric 中称之为 链码,是区块链应用的业务逻辑. 本 ...

随机推荐

  1. Scala教程之:深入理解协变和逆变

    文章目录 函数的参数和返回值 可变类型的变异 在之前的文章中我们简单的介绍过scala中的协变和逆变,我们使用+ 来表示协变类型:使用-表示逆变类型:非转化类型不需要添加标记. 假如我们定义一个cla ...

  2. 还在写CURD?试试这款基于mybatis-plus的springboot代码生成器

    目录 ⚡Introduction ✔️Release Features Quick Start Examples 1.Controller模板代码示例 2.Service模板代码示例 3.Servic ...

  3. Vue项目开发流程(自用)

    一.配置开发环境 1.1 安装Node.js npm集成在Node中,检查是否安装完成:node -v 1.2 安装cnpm(淘宝镜像) npm install -g cnpm,检查安装是否完成:cn ...

  4. Crash日志解析

    当应用程序崩溃时,会创建一个崩溃报告,这对于了解导致崩溃的原因非常有用.本文档包含有关如何表示,理解和解释崩溃报告的基本信息. 1.介绍 2.获取崩溃和低内存报告 3.象征性的奔溃报告 1.位码(bi ...

  5. Netty(四):AbstractChannel源码解析

    首先我们通过一张继承关系的图来认识下AbstractChannel在Netty中的位置. 除了Comaprable接口来自java自带的包,其他都是Netty包中提供的. Comparable接口定义 ...

  6. Java实现zip文件解压[到指定目录]

    2019独角兽企业重金招聘Python工程师标准>>> package com.ljheee.ziptool.core; import java.io.File; import ja ...

  7. php beast windows编译教程

    git clone https://github.com/Microsoft/php-sdk-binary-tools.git c:\php-sdk cd c:\php-sdk git checkou ...

  8. NodeJS反向代理websocket

    如需转载请标明出处:http://blog.csdn.net/itas109QQ技术交流群:129518033 文章目录NodeJS反向代理websocket@[toc]前言代码相关问题:1.http ...

  9. 在for循环里面的++i与i++的区别

    ++i与i++在表面上没有什么区别 for(语句 1;语句 2;语句 3) 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块)的条件 语句 3 在循环(代码块)已被执行之后执行 ( ...

  10. 使用 vi 命令创建一个cpp文件

    mkdir text //创建一个text的文件夹 cd text //打开text的文件夹 vi text.cpp //创建text.cpp 按住 i 键输入程序 输入后按esc,再按wq退出 ls ...