Hyperledger Fabric——balance transfer(六)查詢
阿新 • • 發佈:2019-01-24
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 |