在 Hyperledher Fabric V1.0 的本地开发环境中使用 fabric client java sdk(因为没有 Rest API 支持)时出现问题
Issue while using fabric client java sdk (since there is no Rest API support) in local development environment for Hyperledher Fabric V1.0
我根据 的建议完成了以下操作,以便与来自 java 应用程序的本地 运行 Hyperledger Fabric V1.0 网络进行通信。但是我收到下面给出的异常,无法弄清楚为什么会这样。
public class Test {
final HFClient client = HFClient.createNewInstance();
Channel channel;
TransactionProposalRequest proposalRequest;
void setupCryptoMaterialsForClient() throws CryptoException, InvalidArgumentException{
// Set default crypto suite for HF client
client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
client.setUserContext(new User() {
public String getName() {
return "PeerAdmin";
}
public Set<String> getRoles() {
return null;
}
public String getAccount() {
return null;
}
public String getAffiliation() {
return null;
}
public Enrollment getEnrollment() {
return new Enrollment() {
public PrivateKey getKey() {
PrivateKey privateKey = null;
try {
File privateKeyFile = findFileSk("C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore");
privateKey = getPrivateKeyFromBytes(IOUtils.toByteArray(new FileInputStream(privateKeyFile)));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return privateKey;
}
public String getCert() {
String certificate = null;
try {
File certificateFile = new File("C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem");
certificate = new String(IOUtils.toByteArray(new FileInputStream(certificateFile)), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return certificate;
}
};
}
public String getMspId() {
return "Org1MSP";
}
});
}
static File findFileSk(String directorys) {
File directory = new File(directorys);
File[] matches = directory.listFiles((dir, name) -> name.endsWith("_sk"));
if (null == matches) {
throw new RuntimeException(format("Matches returned null does %s directory exist?", directory.getAbsoluteFile().getName()));
}
if (matches.length != 1) {
throw new RuntimeException(format("Expected in %s only 1 sk file but found %d", directory.getAbsoluteFile().getName(), matches.length));
}
return matches[0];
}
static PrivateKey getPrivateKeyFromBytes(byte[] data) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
final Reader pemReader = new StringReader(new String(data));
final PrivateKeyInfo pemPair;
try (PEMParser pemParser = new PEMParser(pemReader)) {
pemPair = (PrivateKeyInfo) pemParser.readObject();
}
PrivateKey privateKey = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getPrivateKey(pemPair);
return privateKey;
}
void createChannel() throws InvalidArgumentException, TransactionException{
channel = client.newChannel("mychannel");
Properties ordererProperties = new Properties();
ordererProperties.setProperty("pemFile", "C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt");
ordererProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
ordererProperties.setProperty("hostnameOverride", "orderer.example.com");
ordererProperties.setProperty("sslProvider", "openSSL");
ordererProperties.setProperty("negotiationType", "TLS");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
channel.addOrderer(client.newOrderer("orderer.example.com", "grpc://192.168.99.100:7050",ordererProperties));
Properties peerProperties = new Properties();
peerProperties.setProperty("pemFile", "C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt");
peerProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
peerProperties.setProperty("hostnameOverride", "peer0.org1.example.com");
peerProperties.setProperty("sslProvider", "openSSL");
peerProperties.setProperty("negotiationType", "TLS");
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
channel.addPeer(client.newPeer("peer0.org1.example.com", "grpc://192.168.99.100:7051",peerProperties));
channel.initialize();
}
void creteTransactionalProposal(){
proposalRequest = client.newTransactionProposalRequest();
final ChaincodeID chaincodeID = ChaincodeID.newBuilder()
.setName("asset")
.setVersion("1.0")
.setPath("github.com/mygitId/myFabricRepo/assetChainCode")
.build();
proposalRequest.setChaincodeID(chaincodeID);
proposalRequest.setFcn("createAsset");
//proposalRequest.setFcn("init");
proposalRequest.setProposalWaitTime(TimeUnit.SECONDS.toMillis(10));
proposalRequest.setArgs(new String[]{"ORG1", "{\"assetKey\":\"a1\",\"assetName\":\"aname1\",\"assetType\":\"atype1\",\"slNo\":\"slno1\",\"orderDate\":\"19-05-2017\"}"});
}
void sendProposal() throws ProposalException, InvalidArgumentException, InterruptedException, ExecutionException{
final Collection<ProposalResponse> responses = channel.sendTransactionProposal(proposalRequest);
CompletableFuture<BlockEvent.TransactionEvent> txFuture = channel.sendTransaction(responses, client.getUserContext());
BlockEvent.TransactionEvent event = txFuture.get();
System.out.println(event.toString());
}
public static void main(String args[]) throws Exception {
Test t = new Test();
t.setupCryptoMaterialsForClient();
t.createChannel();
t.creteTransactionalProposal();
t.sendProposal();
}
}
这是我的 docker ps
并且通过 运行 eclipse java 项目中的代码得到以下异常。
Exception in thread "main" org.hyperledger.fabric.sdk.exception.TransactionException: INTERNAL
at org.hyperledger.fabric.sdk.OrdererClient.sendDeliver(OrdererClient.java:286)
at org.hyperledger.fabric.sdk.Orderer.sendDeliver(Orderer.java:165)
at org.hyperledger.fabric.sdk.Channel.getLatestBlock(Channel.java:1074)
at org.hyperledger.fabric.sdk.Channel.getConfigurationBlock(Channel.java:898)
at org.hyperledger.fabric.sdk.Channel.parseConfigBlock(Channel.java:826)
at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:526)
at com.ibs.blockchain.client.test.Test.createChannel(Test.java:151)
at com.ibs.blockchain.client.test.Test.main(Test.java:179)
Caused by: io.grpc.StatusRuntimeException: INTERNAL
at io.grpc.Status.asRuntimeException(Status.java:540)
at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:392)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access0(ClientCallImpl.java:76)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:512)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access0(ClientCallImpl.java:429)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImplStreamClosed.runInContext(ClientCallImpl.java:544)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:52)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:117)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: io.netty.handler.codec.http2.Http2Exception: First received frame was not SETTINGS. Hex dump for first 5 bytes: 1503010002
at io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:85)
at io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.verifyFirstFrameIsSettings(Http2ConnectionHandler.java:309)
at io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:217)
at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:401)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
... 1 more
有人请查看代码帮助我找到我做错的地方。
给的ip192.168.99.100
是虚拟机ip
注:
我正在使用 Windows 7 与 Docker Toolbox by following the steps Building Your First Network 和 运行 我的 java 通过 eclipse 的应用程序。
更新:
根据@Gari Singh 的回答通过参考 fabric-sdk-java 来源添加 TLS 来更新函数 createChannel
。但现在也是同样的错误。
更新:
docker 运行 java 客户端之后的快速启动终端控制台,似乎没有日志出现
如果您使用了 first-network 示例,它已启用 TLS,而在您上面的代码中您没有使用 TLS。所以我最好的猜测是错误是由于您的客户端未使用 TLS 引起的。
您是如何创建加密货币 material 的?!我不是在问您使用的工具,我的问题与您为证书定义的通用名称更相关。证书的 CN 必须与您要连接的主机相同。
如果我是你,我会使用 cryptogen 工具创建加密 material。然后,我会更改调用的 URL。我知道您在本地主机中,所以您可以尝试调用 orderer.example.com.
而不是 192.168.99.100
另一方面,我认为您不必执行 createchannel
,因为您之前已经创建了它。
我根据
public class Test {
final HFClient client = HFClient.createNewInstance();
Channel channel;
TransactionProposalRequest proposalRequest;
void setupCryptoMaterialsForClient() throws CryptoException, InvalidArgumentException{
// Set default crypto suite for HF client
client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
client.setUserContext(new User() {
public String getName() {
return "PeerAdmin";
}
public Set<String> getRoles() {
return null;
}
public String getAccount() {
return null;
}
public String getAffiliation() {
return null;
}
public Enrollment getEnrollment() {
return new Enrollment() {
public PrivateKey getKey() {
PrivateKey privateKey = null;
try {
File privateKeyFile = findFileSk("C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore");
privateKey = getPrivateKeyFromBytes(IOUtils.toByteArray(new FileInputStream(privateKeyFile)));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return privateKey;
}
public String getCert() {
String certificate = null;
try {
File certificateFile = new File("C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem");
certificate = new String(IOUtils.toByteArray(new FileInputStream(certificateFile)), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return certificate;
}
};
}
public String getMspId() {
return "Org1MSP";
}
});
}
static File findFileSk(String directorys) {
File directory = new File(directorys);
File[] matches = directory.listFiles((dir, name) -> name.endsWith("_sk"));
if (null == matches) {
throw new RuntimeException(format("Matches returned null does %s directory exist?", directory.getAbsoluteFile().getName()));
}
if (matches.length != 1) {
throw new RuntimeException(format("Expected in %s only 1 sk file but found %d", directory.getAbsoluteFile().getName(), matches.length));
}
return matches[0];
}
static PrivateKey getPrivateKeyFromBytes(byte[] data) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
final Reader pemReader = new StringReader(new String(data));
final PrivateKeyInfo pemPair;
try (PEMParser pemParser = new PEMParser(pemReader)) {
pemPair = (PrivateKeyInfo) pemParser.readObject();
}
PrivateKey privateKey = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getPrivateKey(pemPair);
return privateKey;
}
void createChannel() throws InvalidArgumentException, TransactionException{
channel = client.newChannel("mychannel");
Properties ordererProperties = new Properties();
ordererProperties.setProperty("pemFile", "C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt");
ordererProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
ordererProperties.setProperty("hostnameOverride", "orderer.example.com");
ordererProperties.setProperty("sslProvider", "openSSL");
ordererProperties.setProperty("negotiationType", "TLS");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
channel.addOrderer(client.newOrderer("orderer.example.com", "grpc://192.168.99.100:7050",ordererProperties));
Properties peerProperties = new Properties();
peerProperties.setProperty("pemFile", "C:/Users/Public/HyperledgerFabricV1/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt");
peerProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
peerProperties.setProperty("hostnameOverride", "peer0.org1.example.com");
peerProperties.setProperty("sslProvider", "openSSL");
peerProperties.setProperty("negotiationType", "TLS");
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
channel.addPeer(client.newPeer("peer0.org1.example.com", "grpc://192.168.99.100:7051",peerProperties));
channel.initialize();
}
void creteTransactionalProposal(){
proposalRequest = client.newTransactionProposalRequest();
final ChaincodeID chaincodeID = ChaincodeID.newBuilder()
.setName("asset")
.setVersion("1.0")
.setPath("github.com/mygitId/myFabricRepo/assetChainCode")
.build();
proposalRequest.setChaincodeID(chaincodeID);
proposalRequest.setFcn("createAsset");
//proposalRequest.setFcn("init");
proposalRequest.setProposalWaitTime(TimeUnit.SECONDS.toMillis(10));
proposalRequest.setArgs(new String[]{"ORG1", "{\"assetKey\":\"a1\",\"assetName\":\"aname1\",\"assetType\":\"atype1\",\"slNo\":\"slno1\",\"orderDate\":\"19-05-2017\"}"});
}
void sendProposal() throws ProposalException, InvalidArgumentException, InterruptedException, ExecutionException{
final Collection<ProposalResponse> responses = channel.sendTransactionProposal(proposalRequest);
CompletableFuture<BlockEvent.TransactionEvent> txFuture = channel.sendTransaction(responses, client.getUserContext());
BlockEvent.TransactionEvent event = txFuture.get();
System.out.println(event.toString());
}
public static void main(String args[]) throws Exception {
Test t = new Test();
t.setupCryptoMaterialsForClient();
t.createChannel();
t.creteTransactionalProposal();
t.sendProposal();
}
}
这是我的 docker ps
并且通过 运行 eclipse java 项目中的代码得到以下异常。
Exception in thread "main" org.hyperledger.fabric.sdk.exception.TransactionException: INTERNAL
at org.hyperledger.fabric.sdk.OrdererClient.sendDeliver(OrdererClient.java:286)
at org.hyperledger.fabric.sdk.Orderer.sendDeliver(Orderer.java:165)
at org.hyperledger.fabric.sdk.Channel.getLatestBlock(Channel.java:1074)
at org.hyperledger.fabric.sdk.Channel.getConfigurationBlock(Channel.java:898)
at org.hyperledger.fabric.sdk.Channel.parseConfigBlock(Channel.java:826)
at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:526)
at com.ibs.blockchain.client.test.Test.createChannel(Test.java:151)
at com.ibs.blockchain.client.test.Test.main(Test.java:179)
Caused by: io.grpc.StatusRuntimeException: INTERNAL
at io.grpc.Status.asRuntimeException(Status.java:540)
at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:392)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access0(ClientCallImpl.java:76)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:512)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access0(ClientCallImpl.java:429)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImplStreamClosed.runInContext(ClientCallImpl.java:544)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:52)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:117)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: io.netty.handler.codec.http2.Http2Exception: First received frame was not SETTINGS. Hex dump for first 5 bytes: 1503010002
at io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:85)
at io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.verifyFirstFrameIsSettings(Http2ConnectionHandler.java:309)
at io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:217)
at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:401)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
... 1 more
有人请查看代码帮助我找到我做错的地方。
给的ip192.168.99.100
是虚拟机ip
注: 我正在使用 Windows 7 与 Docker Toolbox by following the steps Building Your First Network 和 运行 我的 java 通过 eclipse 的应用程序。
更新:
根据@Gari Singh 的回答通过参考 fabric-sdk-java 来源添加 TLS 来更新函数 createChannel
。但现在也是同样的错误。
更新:
docker 运行 java 客户端之后的快速启动终端控制台,似乎没有日志出现
如果您使用了 first-network 示例,它已启用 TLS,而在您上面的代码中您没有使用 TLS。所以我最好的猜测是错误是由于您的客户端未使用 TLS 引起的。
您是如何创建加密货币 material 的?!我不是在问您使用的工具,我的问题与您为证书定义的通用名称更相关。证书的 CN 必须与您要连接的主机相同。
如果我是你,我会使用 cryptogen 工具创建加密 material。然后,我会更改调用的 URL。我知道您在本地主机中,所以您可以尝试调用 orderer.example.com.
而不是 192.168.99.100另一方面,我认为您不必执行 createchannel
,因为您之前已经创建了它。