超级组织结构JAVA SDK的多个组织的认可

时间:2019-07-17 23:40:29

标签: hyperledger-fabric blockchain hyperledger hyperledger-fabric-sdk-java

我正在使用Hyperledger Fabric v1.4第一网络示例来建立一个由两个组织和四个对等方组成的区块链网络。 Here是在安装程序中运行的docker进程的屏幕截图。

第一个网络示例使用的签注策略为AND ('Org1MSP.peer','Org2MSP.peer'),默认链码为chaincode_example02

要与网络通信,我正在使用JAVA SDK v1.4.1。我能够注册创建HF客户端和频道等,也能够创建用户并查询(读取)区块链而没有任何问题。

我面临的问题是尝试使用“调用”功能更新区块链时。

这是我在Java方面看到的堆栈跟踪

2019-07-17 23:34:41,811 INFO  [http-nio-8080-exec-6] com.invincible.ngi.service.UtilityService: New channel initialized:mychannel
2019-07-17 23:34:41,812 INFO  [http-nio-8080-exec-6] com.invincible.ngi.service.UtilityService: Order added to the channel:orderer.example.com
2019-07-17 23:34:41,813 INFO  [http-nio-8080-exec-6] com.invincible.ngi.service.UtilityService: Peer added to the channel:peer0.org1.example.com
2019-07-17 23:34:43,570 INFO  [http-nio-8080-exec-6] org.hyperledger.fabric.sdk.Channel: Channel Channel{id: 6, name: mychannel} eventThread started shutdown: false  thread: null 
2019-07-17 23:34:46,696 ERROR [http-nio-8080-exec-6] com.invincible.ngi.service.QueryService: org.hyperledger.fabric.sdk.exception.TransactionEventException: Received invalid transaction event. Transaction ID 753436574ea481148f9d2da7d793f0ff1630c0c4b3106995240cf8b73aa1f1db status 10
java.util.concurrent.ExecutionException: org.hyperledger.fabric.sdk.exception.TransactionEventException: Received invalid transaction event. Transaction ID 753436574ea481148f9d2da7d793f0ff1630c0c4b3106995240cf8b73aa1f1db status 10
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
    at com.invincible.ngi.service.QueryService.updateBlockChain(QueryService.java:56)
    at com.invincible.ngi.resource.QueryResource.updateQuery(QueryResource.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.hyperledger.fabric.sdk.exception.TransactionEventException: Received invalid transaction event. Transaction ID 753436574ea481148f9d2da7d793f0ff1630c0c4b3106995240cf8b73aa1f1db status 10
    at org.hyperledger.fabric.sdk.Channel$TL.lambda$fire$2(Channel.java:6227)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    ... 1 common frames omitted
2019-07-17 23:34:46,703 ERROR [http-nio-8080-exec-6] org.apache.juli.logging.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [/api] threw exception [Request processing failed; nested exception is java.util.concurrent.ExecutionException: org.hyperledger.fabric.sdk.exception.TransactionEventException: Received invalid transaction event. Transaction ID 753436574ea481148f9d2da7d793f0ff1630c0c4b3106995240cf8b73aa1f1db status 10] with root cause
org.hyperledger.fabric.sdk.exception.TransactionEventException: Received invalid transaction event. Transaction ID 753436574ea481148f9d2da7d793f0ff1630c0c4b3106995240cf8b73aa1f1db status 10
    at org.hyperledger.fabric.sdk.Channel$TL.lambda$fire$2(Channel.java:6227)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

this出现在每个对等节点中

在调查中,我发现该问题是有效的,因为背书预期交易将由每个组织中的至少一位同行签署。这就是我初始化频道的方式。

    Channel channel = client.newChannel(ngiProperties.getChannel());
    logger.info("New channel initialized:" + ngiProperties.getChannel());
    Properties ordererProperties = new Properties();
    ordererProperties.setProperty("pemFile", ngiProperties.getOrdererServerCert());
    ordererProperties.setProperty("trustServerCertificate", ngiProperties.getOrdererTrustServerCertificate());
    ordererProperties.setProperty("hostnameOverride", ngiProperties.getOrdererHostnameOverride());
    ordererProperties.setProperty("sslProvider", ngiProperties.getOrdererSslProvider());
    ordererProperties.setProperty("negotiationType", ngiProperties.getOrdererNegotiationType());
    ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[]{ngiProperties.getOrdererKeepAliveTime(), TimeUnit.MINUTES});
    ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[]{ngiProperties.getOrdererKeepAliveTimeout(), TimeUnit.SECONDS});
    channel.addOrderer(client.newOrderer(ngiProperties.getOrdererHost(), ngiProperties.getOrdererGrpc(), ordererProperties));
    logger.info("Order added to the channel:" + ngiProperties.getOrdererHost()); // orderer.example.com
    Properties peerProperties = new Properties();
    peerProperties.setProperty("pemFile", ngiProperties.getPeerAServerCert());
    peerProperties.setProperty("trustServerCertificate", ngiProperties.getPeerATrustServerCertificate());
    peerProperties.setProperty("hostnameOverride", ngiProperties.getPeerAHostnameOverride());
    peerProperties.setProperty("sslProvider", ngiProperties.getPeerASslProvider());
    peerProperties.setProperty("negotiationType", ngiProperties.getPeerANegotiationType());
    channel.addPeer(client.newPeer(ngiProperties.getPeerAHost(), ngiProperties.getPeerAGrpc(), peerProperties));
    logger.info("Peer added to the channel:" + ngiProperties.getPeerAHost()); // peer0.org1.example.com
    channel.initialize();

现在我意识到的是,如果仅在通道中添加来自org2的另一个对等体,就可以解决该问题,即只需在初始化通道之前添加以下代码即可

    peerProperties = new Properties();
    peerProperties.setProperty("pemFile", ngiProperties.getPeerCServerCert());
    peerProperties.setProperty("trustServerCertificate", ngiProperties.getPeerCTrustServerCertificate());
    peerProperties.setProperty("hostnameOverride", ngiProperties.getPeerCHostnameOverride());
    peerProperties.setProperty("sslProvider", ngiProperties.getPeerCSslProvider());
    peerProperties.setProperty("negotiationType", ngiProperties.getPeerCNegotiationType());
    channel.addPeer(client.newPeer(ngiProperties.getPeerCHost(), ngiProperties.getPeerCGrpc(), peerProperties));
    logger.info("Peer added to the channel:" + ngiProperties.getPeerCHost()); // peer0.org2.example.com

关于这个,我有几个问题

  1. 如果仅通过在通道初始化中添加所需的认可对等方来实现交易的有效性,那么执行认可规则的意义何在?如果org1以某种方式设法获得org2的对等详细信息,那么org1可以在未经org2同意的情况下提交事务?
  2. 设置将要向HFClient提交交易的用户的目的是什么?交易过程中,Fabric在哪里以及如何验证用户上下文及其注册?
  3. 理想情况下,我希望如果我有AND ('Org1MSP.peer','Org2MSP.peer')作为背书政策并有一个UI来提交交易,HFClient中设置的用户上下文应具有“ Org1MSP.peer”签名,而org2中的用户应具有“ Org2MSP.peer'应该收到有关提交的交易的通知。仅当具有签名“ Org2MSP.peer”的任何用户对其进行签名时,才应提交事务。不管我使用过多少个初始化通道的对等端,所有这些都应该发生。我的期望有效吗?如果是的话,如何使用Fabric JAVA SDK实现它?

1 个答案:

答案 0 :(得分:1)

  

如果仅通过添加交易即可达到交易的有效性   通道初始化中需要认可的同级,什么是   执行背书规则的要点?如果org1以某种方式设法获得   org2的对等详细信息,org1可以提交事务而无需   得到org2的同意?

  1. 认可对等点是安装链码的对等点。 现在,当您的客户发送交易建议时, 背书,它首先检查结构运行时的背书策略。在你的情况下 是AND('Org1MSP.peer','Org2MSP.peer'),这意味着 背书人应返回提案回复,但您只有一个 对等体在通道上,所以它在第一步本身失败 不符合认可政策规则。 **执行背书政策提供了一种方法,可以管理一对一和双倍支出的数据篡改。** here上的详细概述。

  2. 由于网络将是分布式的,所以几乎任何组织都无法做到 访问任何其他组织的证书。

P.S交易签名是一个自动过程,组织中没有人会手动签名。

希望这会有所帮助。

  

设置提交用户的用户有什么意义?   交易到HFClient?该用户上下文及其位置以及位置   交易过程中通过Fabric验证的注册?

要知道谁想要更改区块链中的数据状态,例如,当org1要更改汽车的所有权时,那么当提交数据时,就会知道谁更改了汽车的所有权。

  

理想情况下,我希望我将AND('Org1MSP.peer','Org2MSP.peer')设置为   背书政策并有一个UI提交交易,用户   HFClient中设置的上下文应具有“ Org1MSP.peer”签名   并且使用“ Org2MSP.peer”的org2中的用户应收到有关   提交的交易。交易只应提交   任何具有签名“ Org2MSP.peer”的用户对其进行签名。而所有这些   不管我曾经初始化过多少个同伴   这个频道。我的期望有效吗?如果是这样,如何实现   织物JAVA SDK?

好吧,客户只需发送交易建议,即要执行的操作和元数据,并使用其私钥进行签名。chaincode容器将负责自己的证书。没有真正的人会手动签署交易建议书,它是自动的 背书方执行的过程。