关于与Java应用程序的智能契约交互的工作流(顺序),我有很多疑问,所以我将首先解释我做了什么,然后提出问题,如果我的理解有什么问题,请告诉我。
我已经编写了智能契约2-使用松露来获得智能契约java包装。(contract.java) 3-使用testrpc测试合同。
我有两个类使用testrpc帐户(凭据)与智能契约进行交互并调用其函数。
每个类(node1.java,node2.java)调用一个名为( send )的智能契约中的函数,将其数据发送到链中。
我添加了一个事件,如果两个节点发送了数据,就会触发该事件。
我不明白的是,如何让java代码(比方说MainProgram.class)始终检查该事件。因为我需要检查两个节点是否发送数据,所以我将调用另一个函数来分析这些数据。
如何管理、控制和检查已完成或未完成的事务,我的意思是如何使用java代码中的事件,让代码永远运行,并检查该事件是否发生,执行操作。
希望我能清楚地解释我需要的东西
提前谢谢你。
发布于 2018-03-04 00:00:02
我对你的一个以前的问题的回答适用于这里。是的,您可能希望设置一个专门的进程来侦听事件。但是,你不需要一个帐户,甚至不需要成为一个智能合同的所有者或客户来监听公共区块链上的事件(这就是为什么它被认为是“公共的”)。
为了倾听事件,你所需要的只是合同ABI和合同地址。这两者对你来说都应该很容易得到。您可以在该契约发出的所有事件上设置一个侦听器。来自web3j文档
使用EthFilter类型指定希望应用于筛选器的主题。这可以包括您希望应用筛选器的智能契约的地址。您还可以提供要筛选的特定主题。其中各个主题表示smart合同上的索引参数: EthFilter filter =新的EthFilter(DefaultBlockParameterName.EARLIEST,DefaultBlockParameterName.LATEST,).addSingleTopic(.)x.addOptionalTopics(.,.) 然后,可以使用与上述块和事务筛选器类似的语法创建此筛选器: web3j.ethLogObservable(filter).subscribe(log -> {. });
指定块参数可以让您决定在历史记录中要开始处理事件的时间。请记住,在Ethereum中,事件实际上是块链上的日志。当您侦听事件时,您实际上是在寻找日志中的活动,因为块被添加到链中。因此,您可以在历史上尽可能地追溯到您想要的地方,并查看旧的块来处理旧事件。
要倾听合同中的所有事件,你只需做:
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, <CONTRACT_ADDRESS>);
web3.ethLogObservable(filter).subscribe(log -> System.out.println(log.toString());关于ETHFILTER的合同地址的重要注意事项-- EthFilter中的合同地址在Web3j中有一个错误。API不喜欢合同地址中的前面的'0x‘。要解决这个问题,如果您使用的是合同对象,请使用contract.getContractAddress().substring(2);发送合同地址
如果您对特定事件感兴趣,则需要将主题添加到筛选器中。下面的示例将侦听抛出的所有MyEvent事件,其中包含一个索引地址参数和两个非索引的uint256参数:
Web3j web3j = Web3j.build(new HttpService());
Event event = new Event("MyEvent",
Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}),
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}));
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, <CONTRACT_ADDRESS>);
filter.addSingleTopic(EventEncoder.encode(event));
web3j.ethLogObservable(filter).subscribe(log -> System.out.println(log.toString()));上述内容可以在任何服务器进程中运行。在服务器进程中,可以通过本地节点(使用new HttpService()时的默认本地主机)连接到网络。或者,您可以与恩弗拉签约,创建一个API键,并使用和使用它们的节点集群(例如Ropsten URL:new HttpService("https://ropsten.infura.io/<YOUR_API_KEY>");)
https://stackoverflow.com/questions/49083825
复制相似问题