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基本上都在前面初始化链码等出现过

阅读更多

更多精彩内容