1. 程式人生 > >Hyperledger Fabric——balance transfer(六)查詢

Hyperledger Fabric——balance transfer(六)查詢

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