Я пытаюсь следовать этому руководству: https://hyperledger.github.io/fabric-sdk-node/release-1.4/tutorial-sign-transaction-offline.html
Я создал полную сеть Hyperledger Fabri c, используя это руководство: https://hyperledger-fabric-ca.readthedocs.io/en/latest/operations_guide.html
SDK Javascript работает хорошо, и я могу запрашивать / вызывать транзакции с помощью метода client.setUserContext ().
При попытке подписать транзакцию в автономном режиме предложение по транзакции отклоняется одноранговые узлы со следующим ответом:
{ Error: 2 UNKNOWN: access denied: channel [mychannel] creator org [org1]
at Object.exports.createStatusError ([...]/node_modules/grpc/src/common.js:91:15)
at Object.onReceiveStatus ([...]/node_modules/grpc/src/client_interceptors.js:1204:28)
at InterceptingListener._callNext ([...]/node/node_modules/grpc/src/client_interceptors.js:568:42)
at InterceptingListener.onReceiveStatus ([...]/node/node_modules/grpc/src/client_interceptors.js:618:8)
at callback ([...]/node/node_modules/grpc/src/client_interceptors.js:845:24)
code: 2,
metadata: Metadata { _internal_repr: {} },
details: 'access denied: channel [mychannel] creator org [org1]' }
В журналах одноранговых узлов я вижу следующую ошибку:
peer1-org1 | 2020-01-13 21:47:31.569 UTC [protoutils] ValidateProposalMessage -> WARN 078 channel [mychannel]: creator's signature over the proposal is not valid: The signature is invalid
Я не понимаю, почему подпись отклонена. Я внимательно следил за всеми этапами урока. Вот полный код клиента:
//
// Imports
//
var Client = require('fabric-client');
var path = require('path');
var util = require('util');
var fs = require('fs');
const crypto = require('crypto');
const elliptic = require('elliptic');
const { KEYUTIL } = require('jsrsasign');
const config = require('./config');
//
// Script configuartion variables
//
var fcn = 'set';
var args = ["a","60"];
var priv = fs.readFileSync(config.PRIV, 'utf8');
var { prvKeyHex } = KEYUTIL.getKey(priv,'passphrase');
var cert = fs.readFileSync(config.CERT, 'utf8');
const EC = elliptic.ec;
const ecdsaCurve = elliptic.curves['p256'];
const ecdsa = new EC(ecdsaCurve);
const signKey = ecdsa.keyFromPrivate(prvKeyHex, 'hex');
//
// Config init
//
var client = Client.loadFromConfig('network_org1.yaml');
var targets = client.getPeersForOrg('org1');
//
// Main
//
client.initCredentialStores()
.then((nothing) => {
channel = client.getChannel(config.CHANNEL_NAME);
// 1. Generate unsigned transaction proposal
var transaction_proposal = {
chaincodeId: config.CHAINCODE_NAME,
channelId: config.CHANNEL_NAME,
fcn: fcn,
args: args,
};
var { proposal, tx_id } = channel.generateUnsignedProposal(transaction_proposal, 'org1', cert);
// 2. Hash the transaction proposal
var proposalBytes = proposal.toBuffer();
var digest = client.getCryptoSuite().hash(proposalBytes);
//const hash = crypto.createHash('sha256');
//hash.update(proposalBytes);
//var digest = hash.digest('hex');
// 3. Calculate the signature for this transacton proposal
console.log("digest: "+digest);
console.log("signKey: ");
console.log(util.inspect(signKey));
var sig = ecdsa.sign(Buffer.from(digest, 'hex'), signKey);
var signature = Buffer.from(sig.toDER());
var signedProposal = {
signature,
proposal_bytes: proposalBytes,
};
// 4. Send the signed transaction proposal
var proposal_request = {
signedProposal,
targets
}
channel.sendSignedProposal(proposal_request)
.then((proposalResponses) => {
console.log('Proposal responses:');
console.log(util.inspect(proposalResponses));
// TODO: Understand why the proposal signature is rejected by the peers
// 5. Generate unsigned transaction
var transaction_request = {
proposalResponses,
proposal,
};
return channel.generateUnsignedTransaction(transaction_request);
})
.then((commitProposal) => {
// 6. Sign the unsigned transaction
var transactionBytes = commitProposal.toBuffer();
var transaction_digest = client.getCryptoSuite().hash(transactionBytes);
var transaction_sig = ecdsa.sign(Buffer.from(transaction_digest, 'hex'), signKey);
var transaction_signature = Buffer.from(transaction_sig.toDER());
var signedTransaction = {
signedProposal: transaction_signature,
request: transaction_request
}
// 7. Commit the signed transaction
return channel.sendSignedTransaction(signedTransaction);
})
.then((response) => {
console.log('Successfully sent transaction');
console.log('Return code: '+response.status);
});
});
Любая помощь от любого, кто мог бы успешно подписать транзакции в автономном режиме, была бы fantasti c.