版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/ASN_forever/article/details/89024550
大概过程就是将背书节点添加到channel中,然后构造交易提案请求参数发送交易提案,然后构造交易请求参数,发送交易即可。
我这里在链码实例化的时候指定的背书策略为:AND('Org1MSP.member','Org2MSP.member')
org1中的peer0地址和端口为:192.168.89.131:7051
org2中的peer0地址和端口为:192.168.89.131:8051(下面就以这两个peer为背书节点编写node sdk)
'use strict';
var co = require('co');
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 EventHub = require('fabric-client/lib/EventHub.js');
var User = require('fabric-client/lib/User.js');
var crypto = require('crypto');
var FabricCAService = require('fabric-ca-client');
//定义证书文件的缓存目录,应该也可以用path.join(__dirname, 'fabric-client-kvs')
var tempdir = "/opt/gopath/src/github.com/hyperledger/fabric/scf/node-sdk/fabric-client-kvs"
//创建客户端代理
var client = new hfc();
//创建通道的客户端代理,被创建的通道名字为:mychannel
var channel = client.newChannel('mychannel');
//创建orderer,该orderer运行的服务器地址为:192.168.89.131,创建成功后将该orderer加入到channel中
var order = client.newOrderer('grpc://192.168.89.131:7050');
channel.addOrderer(order);
//创建peer1节点的客户端代理,该peer节点的IP地址为192.168.89.131(如果是运行在本机上,也可用localhost),端口号为:7051
var peer1 = client.newPeer('grpc://192.168.89.131:7051');
channel.addPeer(peer1);
//创建peer2节点的客户端代理,该peer节点的IP地址为192.168.89.131(如果是运行在本机上,也可用localhost),端口号为:8051
var peer2 = client.newPeer('grpc://192.168.89.131:8051');
channel.addPeer(peer2);
//上面将需要背书的peer1和peer2添加到了channel中,这样就可以实现AND多方背书策略
co((function *(){
let member = yield getOrgUser4Local();
// 构造交易提案请求参数
let tx_id = client.newTransactionID();
var request = {
chaincodeId: "example02cc",
fcn: "invoke",
args: ["a","b","1"],
chainId: "mychannel",
txId: tx_id
};
//发送交易提案()
let chaincodeinvokeresult = yield channel.sendTransactionProposal(request);
//获取返回结果
var proposalResponses = chaincodeinvokeresult[0];
var proposal = chaincodeinvokeresult[1];
var header = chaincodeinvokeresult[2];
var all_good = true;
for(var i in proposalResponses){
let one_good = false;
//检验提案响应信息是否正确
if(proposalResponses && proposalResponses[0].response && proposalResponses[0].response.status === 200){
one_good = true;
console.info('transaction proposal was good');
}else{
console.error('transaction proposal was bad');
}
all_good = all_good & one_good;
}
//如果提案响应正确的话,则将交易提交给排序服务
if(all_good){
console.info(util.format(
'Successfully : 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
));
var request = {
proposalResponses: proposalResponses,
proposal: proposal,
header: header
};
var sendPromise = yield channel.sendTransaction(request);
}
console.info(all_good+"all_good")
})())
/**
*根据cryptogen模块生成的账户,通过fabric相关接口进行操作
*这里使用org1组织的user1用户的账号进行操作
*/
function getOrgUser4Local(){
var keyPath = "/opt/gopath/src/github.com/hyperledger/fabric/scf/crypto-config/peerOrganizations/org1.scf.com/users/[email protected]/msp/keystore";
var keyPEM = Buffer.from(readAllFiles(keyPath)[0]).toString();
var certPath = "/opt/gopath/src/github.com/hyperledger/fabric/scf/crypto-config/peerOrganizations/org1.scf.com/users/[email protected]/msp/signcerts";
var certPEM = readAllFiles(certPath)[0].toString();
//var certPEM = Buffer.from(getKeyFilesInDir(certPath)[0]).toString();
return hfc.newDefaultKeyValueStore({
path:tempdir
}).then((store)=>{
client.setStateStore(store);
return client.createUser({
username: 'user87',
mspid: 'CoreOrg1MSP',
cryptoContent:{
privateKeyPEM: keyPEM,
signedCertPEM: certPEM
}
});
});
};
function readAllFiles(dir){
var files = fs.readdirSync(dir);
var certs = [];
files.forEach((file_name) => {
let file_path = path.join(dir,file_name);
let data = fs.readFileSync(file_path);
certs.push(data);
});
return certs;
}