Hyperledger Fabric:检查交易是否已经提交到账本
Hyperledger Fabric: check if the transaction has been committed to the ledger
我有三个客户端应用程序,分别使用 Java、Node.js 和 Go SDK 与我的区块链 Fabric 进行交互。使用它们,我可以成功查询和更新分类帐。
现在我想测量分类帐更新期间的延迟。所以,我想在提交请求之前取一个时间戳,在交易成功提交到账本之后取另一个时间戳,然后计算差值。
我的问题是我找不到任何关于 SDK 的 API for Java、Go 和 Node.js 的完整文档,所以我不知道是否,当方法提交 returns,我可以认为交易已正确提交到账本。
这是我三个客户的代码。
Java:
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);
Node.js:
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');
开始:
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()
这些代码有效。我的问题是:我可以确定在行
之后
channel.sendTransaction(res)
(在Java)
const result = await contract.submitTransaction('mymethod', 'a1');
(在Node.js)
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts))
(围棋)
交易已提交到账本?
我只在文档上发现:
"Submit a transaction to the ledger. The transaction function name will be evaluated on the endorsing peers and then submitted to the ordering service for committing to the ledger." 在 Node.js 在 https://fabric-sdk-node.github.io/release-1.4/module-fabric-network.Contract.html#submitTransaction__anchor
提交事务
和
"Execute prepares and executes transaction using request and optional request options" 在 Go 中执行 https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel#Client.Execute
对于 Java 我找不到文档...而且我也不确定 Node.js 和 Go。
我想我解决了。在每个客户端应用程序中,我尝试在请求后的行中向分类帐添加查询。这个测试的结果是 Node.js 和 Go 版本运行良好:after
const result = await contract.submitTransaction('mymethod', 'a1');
和
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts))
查询结果没问题,我得到了正确的新值。所以这意味着分类帐在方法执行后正确更新。
对于Java版本我是这样解决的:
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());
希望对您有所帮助。当然,如果有人有意见,他们会很好地接受。
另一个答案可以帮助那些可能需要 CLI 中的此功能的人。
默认情况下,CLI return订单收到交易时成功。
等到 peer chaincode invoke
commnad 提交时添加标志 --waitForEvent
这样 cli 将等待来自同行的提交事件。
希望对您有所帮助。
我认为执行此操作的更好方法是使用 Fabric EventHub,这样您就可以注册一个侦听器并在事件提交时接收该事件。使用查询可能会导致您处理不一致的结果并对延迟事务执行重试。
下面的代码片段可以与 NodeSDK 一起使用,我认为会很有用,可以在此处找到更多示例和文档:https://fabric-sdk-node.github.io/release-1.4/tutorial-listening-to-events.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);
我有三个客户端应用程序,分别使用 Java、Node.js 和 Go SDK 与我的区块链 Fabric 进行交互。使用它们,我可以成功查询和更新分类帐。
现在我想测量分类帐更新期间的延迟。所以,我想在提交请求之前取一个时间戳,在交易成功提交到账本之后取另一个时间戳,然后计算差值。
我的问题是我找不到任何关于 SDK 的 API for Java、Go 和 Node.js 的完整文档,所以我不知道是否,当方法提交 returns,我可以认为交易已正确提交到账本。
这是我三个客户的代码。 Java:
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);
Node.js:
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');
开始:
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()
这些代码有效。我的问题是:我可以确定在行
之后channel.sendTransaction(res)
(在Java)
const result = await contract.submitTransaction('mymethod', 'a1');
(在Node.js)
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts))
(围棋) 交易已提交到账本?
我只在文档上发现:
"Submit a transaction to the ledger. The transaction function name will be evaluated on the endorsing peers and then submitted to the ordering service for committing to the ledger." 在 Node.js 在 https://fabric-sdk-node.github.io/release-1.4/module-fabric-network.Contract.html#submitTransaction__anchor
提交事务和
"Execute prepares and executes transaction using request and optional request options" 在 Go 中执行 https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel#Client.Execute
对于 Java 我找不到文档...而且我也不确定 Node.js 和 Go。
我想我解决了。在每个客户端应用程序中,我尝试在请求后的行中向分类帐添加查询。这个测试的结果是 Node.js 和 Go 版本运行良好:after
const result = await contract.submitTransaction('mymethod', 'a1');
和
response, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "mymethod", Args: [][]byte{[]byte("a1")}}, channel.WithRetry(retry.DefaultChannelOpts))
查询结果没问题,我得到了正确的新值。所以这意味着分类帐在方法执行后正确更新。
对于Java版本我是这样解决的:
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());
希望对您有所帮助。当然,如果有人有意见,他们会很好地接受。
另一个答案可以帮助那些可能需要 CLI 中的此功能的人。
默认情况下,CLI return订单收到交易时成功。
等到 peer chaincode invoke
commnad 提交时添加标志 --waitForEvent
这样 cli 将等待来自同行的提交事件。
希望对您有所帮助。
我认为执行此操作的更好方法是使用 Fabric EventHub,这样您就可以注册一个侦听器并在事件提交时接收该事件。使用查询可能会导致您处理不一致的结果并对延迟事务执行重试。
下面的代码片段可以与 NodeSDK 一起使用,我认为会很有用,可以在此处找到更多示例和文档:https://fabric-sdk-node.github.io/release-1.4/tutorial-listening-to-events.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);