来自 hyperledger fabric JAVA SDK 的多个组织的认可
Endorsement from multiple organisations from hyperledger fabric JAVA SDK
我正在使用 Hyperledger Fabric v1.4 first-network example to setup a blockchain network with two organisations and four peers. Here 是 docker 过程 运行 设置的屏幕截图。
第一个网络示例使用 AND ('Org1MSP.peer','Org2MSP.peer')
的背书策略,默认链码是 chaincode_example02
为了与网络通信,我正在使用 JAVA SDK v1.4.1。我能够注册创建 HF 客户端和通道等,也能够毫无问题地创建用户和查询(读取)区块链。
我面临的问题是尝试使用 'invoke' 函数更新区块链时。
这是我在 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(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(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
有了这个我有几个问题
- 如果仅通过在通道初始化中添加所需的背书节点来实现交易的有效性,那么执行背书规则的意义何在?如果 org1 以某种方式设法获取 org2 的对等详细信息,org1 可以在未经 org2 同意的情况下提交交易?
- 设置向 HFClient 提交交易的用户有什么意义?在交易过程中,结构在何处以及如何验证用户上下文及其注册?
- 理想情况下,如果我有
AND ('Org1MSP.peer','Org2MSP.peer')
作为背书策略并有 UI 提交交易,HFClient 中设置的用户上下文应该有 'Org1MSP.peer' 签名和org2 中具有 'Org2MSP.peer' 的用户应该收到有关提交的交易的通知。仅当具有签名 'Org2MSP.peer' 的任何用户签名时才应提交交易。所有这些都应该发生,无论我使用多少对等点来初始化通道。我的期望有效吗?如果是这样,如何使用 fabric JAVA SDK 实现它?
If the validity of a transaction is achieved just by adding the
required endorsing peers in the channel initialisation, what is the
point of enforcing endorsement rule? If org1 somehow manages to get
the peer details of of org2, org1 can commit transactions without
having consent from org2?
背书节点是安装了链代码的节点。
现在,当您的客户发送交易建议时
背书,它首先检查 fabric run-time 上的背书策略。在你的情况下
是 AND('Org1MSP.peer','Org2MSP.peer')
这意味着
背书人应该 return 提案回应,但你只有一个
在频道上对等,所以它在第一步本身就失败了
不符合背书政策规则。
**背书政策的实施提供了一种管理同行篡改数据和双重支出的方法。**非常
here.
的详细概述
由于网络是分布式的,我几乎没有任何组织可以
访问任何其他组织的证书。
P.S 交易签名是一个自动化过程,组织中没有人会手动签署交易。
希望这对您有所帮助。
And what is the point of setting the user who is submitting the
transaction to the HFClient? Where and how that user context and its
enrolment validated by fabric in the transaction process?
在 blockchain.for 示例中,当 org1 想要更改汽车的所有权时,要知道谁想要更改数据状态,那么当提交数据时,就会知道是谁更改了汽车的所有权。
Ideally I would expect if I have AND ('Org1MSP.peer','Org2MSP.peer') as
endorsement policy and have an UI to submit the transaction, the user
context set in the HFClient should have the 'Org1MSP.peer' signature
and the users in org2 with 'Org2MSP.peer' should get notified about
the transation submitted. The transaction should be committed only
when any user with signature 'Org2MSP.peer' signs it. And all these
should happen irrespective of how many peers I have used to initialise
the channel. Is my expectation valid? If so how to achieve it with
fabric JAVA SDK?
好吧,客户端只是发送交易提议,即要执行的操作和它的元数据,并用它的 priavte 签名 key.The 链码容器会自己处理 certs.There 没有人实际上谁会手动签署交易提案,它是一个自动化的
背书节点执行的过程。
我正在使用 Hyperledger Fabric v1.4 first-network example to setup a blockchain network with two organisations and four peers. Here 是 docker 过程 运行 设置的屏幕截图。
第一个网络示例使用 AND ('Org1MSP.peer','Org2MSP.peer')
的背书策略,默认链码是 chaincode_example02
为了与网络通信,我正在使用 JAVA SDK v1.4.1。我能够注册创建 HF 客户端和通道等,也能够毫无问题地创建用户和查询(读取)区块链。
我面临的问题是尝试使用 'invoke' 函数更新区块链时。
这是我在 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(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(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
有了这个我有几个问题
- 如果仅通过在通道初始化中添加所需的背书节点来实现交易的有效性,那么执行背书规则的意义何在?如果 org1 以某种方式设法获取 org2 的对等详细信息,org1 可以在未经 org2 同意的情况下提交交易?
- 设置向 HFClient 提交交易的用户有什么意义?在交易过程中,结构在何处以及如何验证用户上下文及其注册?
- 理想情况下,如果我有
AND ('Org1MSP.peer','Org2MSP.peer')
作为背书策略并有 UI 提交交易,HFClient 中设置的用户上下文应该有 'Org1MSP.peer' 签名和org2 中具有 'Org2MSP.peer' 的用户应该收到有关提交的交易的通知。仅当具有签名 'Org2MSP.peer' 的任何用户签名时才应提交交易。所有这些都应该发生,无论我使用多少对等点来初始化通道。我的期望有效吗?如果是这样,如何使用 fabric JAVA SDK 实现它?
If the validity of a transaction is achieved just by adding the required endorsing peers in the channel initialisation, what is the point of enforcing endorsement rule? If org1 somehow manages to get the peer details of of org2, org1 can commit transactions without having consent from org2?
背书节点是安装了链代码的节点。 现在,当您的客户发送交易建议时 背书,它首先检查 fabric run-time 上的背书策略。在你的情况下 是
AND('Org1MSP.peer','Org2MSP.peer')
这意味着 背书人应该 return 提案回应,但你只有一个 在频道上对等,所以它在第一步本身就失败了 不符合背书政策规则。 **背书政策的实施提供了一种管理同行篡改数据和双重支出的方法。**非常 here. 的详细概述
由于网络是分布式的,我几乎没有任何组织可以 访问任何其他组织的证书。
P.S 交易签名是一个自动化过程,组织中没有人会手动签署交易。
希望这对您有所帮助。
And what is the point of setting the user who is submitting the transaction to the HFClient? Where and how that user context and its enrolment validated by fabric in the transaction process?
在 blockchain.for 示例中,当 org1 想要更改汽车的所有权时,要知道谁想要更改数据状态,那么当提交数据时,就会知道是谁更改了汽车的所有权。
Ideally I would expect if I have AND ('Org1MSP.peer','Org2MSP.peer') as endorsement policy and have an UI to submit the transaction, the user context set in the HFClient should have the 'Org1MSP.peer' signature and the users in org2 with 'Org2MSP.peer' should get notified about the transation submitted. The transaction should be committed only when any user with signature 'Org2MSP.peer' signs it. And all these should happen irrespective of how many peers I have used to initialise the channel. Is my expectation valid? If so how to achieve it with fabric JAVA SDK?
好吧,客户端只是发送交易提议,即要执行的操作和它的元数据,并用它的 priavte 签名 key.The 链码容器会自己处理 certs.There 没有人实际上谁会手动签署交易提案,它是一个自动化的 背书节点执行的过程。