一代码解析
var path = require(‘path’);
var fs = require(‘fs’);
var util = require(‘util’);
var config = require(’…/config.json’);
var helper = require(’./helper.js’);
var logger = helper.getLogger(‘install-chaincode’);
var tx_id = null;
var installChaincode = function(peers, chaincodeName, chaincodePath,
chaincodeVersion, username, org) {
logger.debug(
‘\n============ Install chaincode on organizations ============\n’);
// 设置gopath变量路径指向balance-transfer/artifacts/ 加载chaincode使用
helper.setupChaincodeDeploy();
var channel = helper.getChannelForOrg(org);
var client = helper.getClientForOrg(org);
//1 获取该组织的admin
return helper.getOrgAdmin(org).then((user) => {
//2 封装request
var request = {
targets: helper.newPeers(peers, org), // peer对应的rpc地址
chaincodePath: chaincodePath,
chaincodeId: chaincodeName,
chaincodeVersion: chaincodeVersion
};
//3 发送请求,安装chaincode
return client.installChaincode(request);(1)
}, (err) => {
logger.error('Failed to enroll user ‘’ + username + ‘’. ’ + err);
throw new Error(‘Failed to enroll user ‘’ + username + ‘’. ’ + err);
}).then((results) => {
var proposalResponses = results[0];
var proposal = results[1];
var all_good = true;
// 4 处理返回的结果
for (var i in proposalResponses) {
let one_good = false;
if (proposalResponses && proposalResponses[i].response &&
proposalResponses[i].response.status === 200) {
one_good = true;
logger.info(‘install proposal was good’);
} else {
logger.error(‘install proposal was bad’);
}
all_good = all_good & one_good;
}
// 是否都安装成功
if (all_good) {
logger.info(util.format(
‘Successfully sent install Proposal and received ProposalResponse: Status - %s’,
proposalResponses[0].response.status));
logger.debug(’\nSuccessfully Installed chaincode on organization ’ + org +
‘\n’);
return 'Successfully Installed chaincode on organization ’ + org;
} else {
logger.error(
‘Failed to send install Proposal or receive valid response. Response null or status is not 200. exiting…’
);
return ‘Failed to send install Proposal or receive valid response. Response null or status is not 200. exiting…’;
}
}, (err) => {
logger.error('Failed to send install proposal due to error: ’ + err.stack ?
err.stack : err);
throw new Error('Failed to send install proposal due to error: ’ + err.stack ?
err.stack : err);
});
};
exports.installChaincode = installChaincode;
二 api深度追踪
(1)
* In fabric v1.0, a chaincode must be installed and instantiated before it
* can be called to process transactions.
*
* Chaincode installation is simply uploading the chaincode source and
* dependencies to the peers. This operation is “channel-agnostic” and is
* performed on a peer-by-peer basis. Only the peer organization’s ADMIN
* identities are allowed to perform this operation.
*
* @param {ChaincodeInstallRequest} request - The request object
* @param {Number} timeout - A number indicating milliseconds to wait on the
* response before rejecting the promise with a
* timeout error. This overrides the default timeout
* of the Peer instance and the global timeout in the config settings.
* @returns {Promise} A Promise for a {@link ProposalResponseObject}
*/
installChaincode(request, timeout) {
logger.debug('installChaincode - start');
let error_msg = null;
let peers = null;
if (request) {
try {
peers = this.getTargetPeers(request.targets);
if(!peers) {
peers = this.getPeersForOrgOnChannel(request.channelNames);
}
} catch (err) {
return Promise.reject(err);
}
// Verify that a Peer has been added
if (peers && peers.length > 0) {
logger.debug('installChaincode - found peers ::%s',peers.length);
}
else {
error_msg = 'Missing peer objects in install chaincode request';
}
}
else {
error_msg = 'Missing input request object on install chaincode request';
}
if (!error_msg) error_msg = clientUtils.checkProposalRequest(request, true);
if (!error_msg) error_msg = clientUtils.checkInstallRequest(request);
if (error_msg) {
logger.error('installChaincode error ' + error_msg);
return Promise.reject(new Error(error_msg));
}
const self = this;
const ccSpec = {
type: clientUtils.translateCCType(request.chaincodeType),
chaincode_id: {
name: request.chaincodeId,
path: request.chaincodePath,
version: request.chaincodeVersion
}
};
logger.debug('installChaincode - ccSpec %s ',JSON.stringify(ccSpec));
// step 2: construct the ChaincodeDeploymentSpec
const chaincodeDeploymentSpec = new _ccProto.ChaincodeDeploymentSpec();
chaincodeDeploymentSpec.setChaincodeSpec(ccSpec);
chaincodeDeploymentSpec.setEffectiveDate(clientUtils.buildCurrentTimestamp()); //TODO may wish to add this as a request setting
return _getChaincodePackageData(request, this.isDevMode())
.then((data) => {
// DATA may or may not be present depending on devmode settings
if (data) {
chaincodeDeploymentSpec.setCodePackage(data);
logger.debug('installChaincode - found packaged data');
}
logger.debug('installChaincode - sending deployment spec %s ',chaincodeDeploymentSpec);
// TODO add ESCC/VSCC info here ??????
const lcccSpec = {
type: ccSpec.type,
chaincode_id: {
name: Constants.LSCC
},
input: {
args: [Buffer.from('install', 'utf8'), chaincodeDeploymentSpec.toBuffer()]
}
};
let signer;
let tx_id = request.txId;
if(!tx_id) {
signer = self._getSigningIdentity(true);
tx_id = new TransactionID(signer, true);
} else {
signer = self._getSigningIdentity(tx_id.isAdmin());
}
const channelHeader = clientUtils.buildChannelHeader(
_commonProto.HeaderType.ENDORSER_TRANSACTION,
'', //install does not target a channel
tx_id.getTransactionID(),
null,
Constants.LSCC
);
const header = clientUtils.buildHeader(signer, channelHeader, tx_id.getNonce());
const proposal = clientUtils.buildProposal(lcccSpec, header);
const signed_proposal = clientUtils.signProposal(signer, proposal);
logger.debug('installChaincode - about to sendPeersProposal');
return clientUtils.sendPeersProposal(peers, signed_proposal, timeout)
.then(
function(responses) {
return [responses, proposal];
}
);
});
}