J'ai trois applications clientes qui utilisent respectivement les SDK Java, Node.js et Go pour interagir avec ma blockchain Fabric. En les utilisant, je peux interroger et mettre à jour le grand livre avec succès.
Maintenant, je veux mesurer la latence lors de la mise à jour du livre. Donc, je pensais le faire en prenant un horodatage avant la soumission de la demande et un autre après que la transaction ait été validée avec succès dans le grand livre, puis calculer la différence.
Mon problème est que je ne trouve aucune documentation complète sur l'API du SDK pour Java, Go et Node.js, donc je ne sais pas si, lorsque la méthode de soumission revient, je peux considérer la transaction comme correctement validée dans le grand livre.
Voici le code de mes trois clients. Java:
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts))
Node.js:
const result = await contract.submitTransaction('mymethod', 'a1');
Aller:
channel.sendTransaction(res)
Ces codes fonctionnent. Mon problème est le suivant: puis-je être sûr qu'après les lignes
sdk, err := fabsdk.New(config.FromFile(configFile)) if err != nil { fmt.Printf("failed to create SDK: %v\n", err) return } fmt.Println("SDK created") // Prepare channel client context using client context clientChannelContext := sdk.ChannelContext(channelID, fabsdk.WithUser(userName), fabsdk.WithOrg(orgName)) // ChannelClient is used to query and execute transactions client, err := channel.New(clientChannelContext) if err != nil { fmt.Printf("failed to create new channel client: %v\n", err) return } fmt.Println("channel client created") response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts)) if err != nil { fmt.Printf("failed to execute the invoke function: %v\n", err) } else { fmt.Println("Proposal responses: ") for _, element := range response.Responses { fmt.Printf("Endorser: %s Status: %d ChaincodeStatus: %d\n", element.Endorser, element.Status, element.ChaincodeStatus) } fmt.Println("chaincode transaction completed: " + string(response.Payload)) } // Close SDK sdk.Close()
(en Java)
const gateway = new Gateway(); await gateway.connect(ccp, { wallet: wallet, identity: userName, discovery: { enabled: false } }); // Get the network (channel) our contract is deployed to. const network = await gateway.getNetwork('mychannel'); // Get the contract from the network. const contract = network.getContract('mychaincode'); const result = await contract.submitTransaction('mymethod', 'a1');
(dans Node. js)
NetworkConfig ccp = NetworkConfig.fromJsonFile(networkConfigPath.toFile()); // initialize default cryptosuite and setup the client CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite(); HFClient client = HFClient.createNewInstance(); client.setCryptoSuite(cryptoSuite); Channel channel = client.loadChannelFromConfig(ccp.getChannelNames().iterator().next(), ccp); channel.initialize(); TransactionProposalRequest transactionProposal = client.newTransactionProposalRequest(); // build chaincode id providing the chaincode name ChaincodeID mychaincodeID = ChaincodeID.newBuilder().setName("mychaincode").build(); transactionProposal.setChaincodeID(mychaincodeID); // calling chaincode function transactionProposal.setFcn("mymethod"); transactionProposal.setArgs("a1"); Collection<ProposalResponse> res = channel.sendTransactionProposal(transactionProposal); channel.sendTransaction(res);
(dans Go) la transaction a été validée dans le grand livre?
Je n'ai trouvé cela que sur la documentation:
"Soumettez une transaction dans le grand livre. Le nom de la fonction de transaction sera évalué sur les pairs endosseurs puis soumis au service de commande pour validation dans le grand livre. " pour submitTransaction dans Node.js à https : //fabric-sdk-node.github.io/release-1.4/module-fabric-network.Contract.html#submitTransaction__anchor
et
"Exécuter prépare et exécute la transaction à l'aide des options de requête et de requête facultatives "pour Exécuter in Go à https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel#Client.Execute
Pour Java I ne trouve pas de documentation ... et je ne suis pas sûr non plus de Node.js et Go.
3 Réponses :
Je pense que j'ai résolu. Dans chaque application cliente, j'ai essayé d'ajouter une requête au grand livre la ligne après la demande. Le résultat de ce test est que la version Node.js et Go fonctionne bien: après
NetworkConfig ccp = NetworkConfig.fromJsonFile(networkConfigPath.toFile()); // initialize default cryptosuite and setup the client CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite(); HFClient client = HFClient.createNewInstance(); client.setCryptoSuite(cryptoSuite); Channel channel = client.loadChannelFromConfig(ccp.getChannelNames().iterator().next(), ccp); channel.initialize(); TransactionProposalRequest transactionProposal = client.newTransactionProposalRequest(); // build chaincode id providing the chaincode name ChaincodeID mychaincodeID = ChaincodeID.newBuilder().setName("mychaincode").build(); transactionProposal.setChaincodeID(mychaincodeID); // calling chaincode function transactionProposal.setFcn("mymethod"); transactionProposal.setArgs("a1"); Collection<ProposalResponse> res = channel.sendTransactionProposal(transactionProposal); CompletableFuture<TransactionEvent> cf = channel.sendTransaction(res); TransactionEvent te = cf.get(); logger.info("Status: " + te.isValid()); logger.info("Committed the transaction with transactionID + " + te.getTransactionID());
et
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts))
le résultat de la requête est correct , J'obtiens la nouvelle valeur correcte. Cela signifie donc que le registre est correctement mis à jour après l'exécution de la méthode.
Pour la version Java, j'ai résolu de cette manière:
const result = await contract.submitTransaction('mymethod', 'a1');
utile. Bien sûr, si quelqu'un a des commentaires, ils sont bien acceptés.
Encore une réponse pour aider ceux qui voudront peut-être cette fonctionnalité de la CLI.
Par défaut, la CLI renvoie le succès lorsque la commande reçoit la transaction.
Pour attendre la validation sur peer chaincode invoke
commnad, ajoutez le drapeau --waitForEvent
De cette façon, le cli attendra les événements de commit des pairs.
J'espère que cela vous aidera.
Absolument utile! Je vous remercie!
Je pense que la meilleure façon d'effectuer cela est d'utiliser Fabric EventHub, de cette façon vous enregistrez un auditeur et recevez un événement lorsqu'il est validé. L'utilisation de requêtes peut vous conduire à traiter des résultats incohérents et à effectuer de nouvelles tentatives pour les transactions retardées.
L'extrait de code ci-dessous peut être utilisé avec NodeSDK et je pense qu'il sera utile, d'autres exemples et documentation peuvent être trouvés ici: https://fabric-sdk-node.github.io/release -1.4 / tutoriel-écoute-événements.html
var options = { wallet_path: path.join(__dirname, './creds'), user_id: 'PeerAdmin', channel_id: 'mychannel', chaincode_id: 'fabcar', peer_url: 'grpc://localhost:7051', event_url: 'grpc://localhost:7053', orderer_url: 'grpc://localhost:7050' }; let eh = client.newEventHub(); eh.setPeerAddr(options.event_url); 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') { console.error( 'The transaction was invalid, code = ' + code); reject(); } else { console.log( 'The transaction has been committed on peer ' + eh._ep._endpoint.addr); resolve(); } }); }); eventPromises.push(txPromise);