1. 程式人生 > >balance transfer程式碼解析及api深度追蹤(六)執行鏈碼

balance transfer程式碼解析及api深度追蹤(六)執行鏈碼

一程式碼解析 var path = require(‘path’); var fs = require(‘fs’); var util = require(‘util’); var hfc = require(‘fabric-client’); var Peer = require(‘fabric-client/lib/Peer.js’); var helper = require(’./helper.js’); var logger = helper.getLogger(‘invoke-chaincode’); var EventHub = require(‘fabric-client/lib/EventHub.js’); var ORGS = hfc.getConfigSetting(‘network-config’);

var invokeChaincode = function (peerNames, channelName, chaincodeName, fcn, args, username, org) { logger.debug(util.format(’\n============ invoke transaction on organization %s ==========\n’, org)); var client = helper.getClientForOrg(org); var channel = helper.getChannelForOrg(org); var targets = (peerNames) ? helper.newPeers(peerNames, org) : undefined; var tx_id = null; //1 獲取 jim 使用者( 內部會設定為上下文環境) return helper.getRegisteredUsers(username, org).then((user) => { tx_id = client.newTransactionID(); logger.debug(util.format(‘Sending transaction “%j”’, tx_id)); //2 封裝交易提案請求 var request = { chaincodeId: chaincodeName, fcn: fcn, args: args, chainId: channelName, txId: tx_id }; if (targets) request.targets = targets; //3 傳送交易提案給背書節點 // send proposal to endorser return channel.sendTransactionProposal(request); }, (err) => { logger.error('Failed to enroll user ‘’ + username + ‘’. ’ + err); throw new Error('Failed to enroll user ‘’ + username + ‘’. ’ + err); }).then((results) => { //4 處理背書結果 var proposalResponses = results[0]; var proposal = results[1]; var all_good = true; for (var i in proposalResponses) { let one_good = false; if (proposalResponses && proposalResponses[i].response && proposalResponses[i].response.status === 200) { one_good = true;

logger.info(‘transaction proposal was good’); } else { logger.error(‘transaction proposal was bad’); } all_good = all_good & one_good; } if (all_good) { logger.debug(util.format( ‘Successfully sent Proposal and received ProposalResponse: Status - %s, message - “%s”, metadata - “%s”, endorsement signature: %s’, proposalResponses[0].response.status, proposalResponses[0].response.message, proposalResponses[0].response.payload, proposalResponses[0].endorsement .signature)); //5 如果背書結果ok 封裝正式交易請求 var request = { proposalResponses: proposalResponses, proposal: proposal }; // set the transaction listener and set a timeout of 30sec // if the transaction did not get committed within the timeout period, // fail the test var transactionID = tx_id.getTransactionID(); var eventPromises = []; if (!peerNames) { peerNames = channel.getPeers().map(function (peer) { return peer.getName(); }); }
//5.1
設定事件監聽 並生成帶有超時設定的promise var eventhubs = helper.newEventHubs(peerNames, org); for (let key in eventhubs) { let eh = eventhubs[key]; eh.connect(); let txPromise = new Promise((resolve, reject) => { let handle = setTimeout(() => { eh.disconnect(); reject(); }, 30000); eh.registerTxEvent(transactionID, (tx, code) => { clearTimeout(handle); eh.unregisterTxEvent(transactionID); eh.disconnect(); if (code ! ‘VALID’) { logger.error( ‘The balance transfer transaction was invalid, code = ’ + code); reject(); } else { logger.info( ‘The balance transfer transaction has been committed on peer ’ + eh._ep._endpoint.addr); resolve(); } }); }); eventPromises.push(txPromise); }; //6 傳送交易 var sendPromise = channel.sendTransaction(request); //7 集合所有的promise 並執行 return Promise.all([sendPromise].concat(eventPromises)).then((results) => { logger.debug(’ event promise all complete and testing complete’); return results[0]; // the first returned value is from the ‘sendPromise’ which is from the ‘sendTransaction()’ call }).catch((err) => { logger.error( ‘Failed to send transaction and get notifications within the timeout period.’ ); return ‘Failed to send transaction and get notifications within the timeout period.’; }); } else { logger.error( ‘Failed to send Proposal or receive valid response. Response null or status is not 200. exiting…’ ); return ‘Failed to send Proposal or receive valid response. Response null or status is not 200. exiting…’; } }, (err) => { logger.error('Failed to send proposal due to error: ’ + err.stack ? err.stack : err); return 'Failed to send proposal due to error: ’ + err.stack ? err.stack : err; }).then((response) => { //8 處理第七步返回的結果 if (response.status === ‘SUCCESS’) { logger.info(‘Successfully sent transaction to the orderer.’); return tx_id.getTransactionID(); } else { logger.error('Failed to order the transaction. Error code: ’ + response.status); return 'Failed to order the transaction. Error code: ’ + response.status; } }, (err) => { logger.error('Failed to send transaction due to error: ’ + err.stack ? err .stack : err); return 'Failed to send transaction due to error: ’ + err.stack ? err.stack : err; }); };

exports.invokeChaincode = invokeChaincode; 二api深度追蹤 裡面的api基本上都在前面初始化鏈碼等出現過