Я использую Hyperledger Fabri c Gateway SDK для Java для подключения к моей локальной сети HLF, доступной по умолчанию с расширением платформы IBM blockchain для VSCode. Я развернул умный контракт из примера Create-BlockchainNetwork-IBPV20 (https://github.com/IBM/Create-BlockchainNetwork-IBPV20/blob/master/README.md). Он хорошо работает с клиентом Node.js, способным отправлять и запрашивать данные.
Проблема возникает, когда я делаю то же самое в Java. Я могу подключиться и даже запросить данные, но при попытке отправить транзакцию я получаю следующую ошибку:
Exception in thread "main" org.hyperledger.fabric.gateway.ContractException: Failed to send transaction to the orderer
at org.hyperledger.fabric.gateway.impl.TransactionImpl.commitTransaction(TransactionImpl.java:145)
at org.hyperledger.fabric.gateway.impl.TransactionImpl.submit(TransactionImpl.java:96)
at org.hyperledger.fabric.gateway.impl.ContractImpl.submitTransaction(ContractImpl.java:50)
at com.dai.mastexport.mavenproject1.NewClass.main(NewClass.java:80)
Caused by: java.util.concurrent.ExecutionException: java.lang.Exception: Channel mychannel failed to place transaction 8eb41fb6477ee8162bfcedf28be255bb508043c1811794c761e42a359b31c682 on Orderer. Cause: UNSUCCESSFUL.
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
at org.hyperledger.fabric.gateway.impl.TransactionImpl.commitTransaction(TransactionImpl.java:139)
... 3 more
Caused by: java.lang.Exception: Channel mychannel failed to place transaction 8eb41fb6477ee8162bfcedf28be255bb508043c1811794c761e42a359b31c682 on Orderer. Cause: UNSUCCESSFUL.
at org.hyperledger.fabric.sdk.Channel.doSendTransaction(Channel.java:5722)
at org.hyperledger.fabric.sdk.Channel.sendTransaction(Channel.java:5533)
at org.hyperledger.fabric.gateway.impl.TransactionImpl.commitTransaction(TransactionImpl.java:138)
... 3 more
Caused by: java.lang.Exception: Channel mychannel unsuccessful sendTransaction to orderer localhost:17076 (grpc://localhost:17076)
at org.hyperledger.fabric.sdk.Channel.doSendTransaction(Channel.java:5704)
... 5 more
Caused by: org.hyperledger.fabric.sdk.exception.TransactionException: Channel mychannel, send transactions failed on orderer OrdererClient{id: 6, channel: mychannel, name: localhost:17076, url: grpc://localhost:17076}. Reason: timeout after 10000 ms.
at org.hyperledger.fabric.sdk.OrdererClient.sendTransaction(OrdererClient.java:223)
at org.hyperledger.fabric.sdk.Orderer.sendTransaction(Orderer.java:164)
at org.hyperledger.fabric.sdk.Channel.doSendTransaction(Channel.java:5686)
... 5 more
Тот же код Java работает хорошо, если я подключаюсь к IBM Blockchain на облако. Вот мой код для справки:
public class NewClass {
static {
System.setProperty("org.hyperledger.fabric.sdk.service_discovery.as_localhost", "true");
}
public static void main(String[] args) throws Exception {
String userName = "admin";
String pass = "adminpw";
String msp = "Org1MSP";
String orgName = "Org1MSP";
String channelName = "mychannel";
String connFile = "connection_test.json";
java.nio.file.Path walletDirectory = java.nio.file.Paths.get("../wallets");
Wallet wallet = Wallets.newFileSystemWallet(walletDirectory);
java.nio.file.Path netConfPath = java.nio.file.Paths.get("../conf", connFile);
// Create a CA client for interacting with the CA.
NetworkConfig netConf = NetworkConfig.fromJsonFile(netConfPath.toFile());
HFCAClient caClient = HFCAClient.createNewInstance(netConf.getOrganizationInfo(orgName).getCertificateAuthorities().get(0));
CryptoSuite cryptoSuite = CryptoSuiteFactory.getDefault().getCryptoSuite();
caClient.setCryptoSuite(cryptoSuite);
// Check to see if we've already enrolled the admin user.
Identity user = wallet.get(userName);
if (user == null) {
// Enroll the admin user, and import the new identity into the wallet.
Enrollment enrollment = caClient.enroll(userName, pass);
user = Identities.newX509Identity(msp, enrollment);
wallet.put(userName, user);
}
Gateway.Builder builder = Gateway.createBuilder();
builder.identity(wallet, userName).networkConfig(netConfPath).discovery(true);
// create a gateway connection
try (Gateway gateway = builder.connect()) {
Network net = gateway.getNetwork(channelName);
Contract contract = net.getContract("blockchain-network");
byte[] result = contract.submitTransaction("AddTrader", "traderA", "Mike", "Smith");
System.out.println(new String(result));
}
}
}
Я пробовал разные версии SDK без удачи. До сих пор я заметил, что мой профиль подключения из локальной сети не содержит информации о pem по сравнению с данными из облака. Вот местный профиль:
{
"certificateAuthorities": {
"Org1CA": {
"caName": "ca",
"url": "http://localhost:17050"
}
},
"client": {
"connection": {
"timeout": {
"orderer": "3000",
"peer": {
"endorser": "3000"
}
}
},
"organization": "Org1MSP"
},
"name": "Org1",
"organizations": {
"Org1MSP": {
"certificateAuthorities": [
"Org1CA"
],
"mspid": "Org1MSP",
"peers": [
"Org1Peer1"
]
}
},
"peers": {
"Org1Peer1": {
"url": "grpc://localhost:17051"
}
},
"version": "1.0.0"
}