从Java应用程序(We3j)与智能合约交互

问题描述 投票:2回答:1

我对从Java应用程序与智能合约交互的工作流程(序列)有很多疑问,所以我先解释一下我做了什么,然后提出我的问题,如果我的理解有问题,请告诉我。

1-我写过智能合约2-使用松露获取智能合约java包装器。(contract.java)3-使用testrpc测试合同

我有2个类使用testrpc帐户(凭证)与智能合约交互并调用其功能

每个类(node1.java,node2.java)调用称为(send)的智能合约中的函数,以将其数据发送到链。

我添加了一个事件,如果2个节点已发送数据,则触发该事件

我不明白的是,我怎么能让java代码(让我们说MainProgram.class)总是检查那个事件。因为我需要检查两个节点是否都发送了数据,然后我会调用另一个函数来分析这些数据。

我如何管理,控制和检查已完成的事务,我的意思是我如何在java代码中使用事件并让代码永远运行并检查此事件是否发生,执行操作。

希望我能清楚地解释一下我需要什么

先感谢您。

java eclipse ethereum smartcontracts
1个回答
0
投票

我对你的一个previous questions的回答适用于此。是的,您可能希望设置专门的流程来监听事件。但是,您不需要帐户,甚至不需要智能合约的所有者或客户来收听公共区块链上的事件(这就是为什么它被视为“公开”)。

要听取事件,您需要的只是合同ABI和合同的地址。两者都应该很容易获得。您可以在此合约发出的所有事件上设置侦听器。来自web3j documentation

您可以使用EthFilter类型指定要应用于筛选器的主题。这可以包括您希望应用过滤器的智能合约的地址。您还可以提供要过滤的特定主题。单个主题代表智能合约上的索引参数:

EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST,
        DefaultBlockParameterName.LATEST, <contract-address>)
             [.addSingleTopic(...) | .addOptionalTopics(..., ...) | ...];

然后可以使用与上面的块和事务过滤器类似的语法创建此过滤器:

web3j.ethLogObservable(filter).subscribe(log -> {
    ...
});

通过指定块参数,您可以决定要开始处理事件的历史记录的返回距离。请记住,在以太坊中,事件实际上是区块链上的日志。当您监听事件时,您实际上是在将日志添加到链中时在日志中查找活动。因此,您可以根据需要追溯历史,并查看旧块以处理旧事件。

要收听合同中的所有事件,您只需:

EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, <CONTRACT_ADDRESS>);

web3.ethLogObservable(filter).subscribe(log -> System.out.println(log.toString());

关于ETHFILTER的合同地址的重要说明 - Web3j中有一个关于EthFilter合同地址的错误。 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()时的默认localhost)连接到网络。或者,你可以sign up with Infura,创建一个API密钥,并使用和使用他们的节点集群(例如Ropsten URL:new HttpService("https://ropsten.infura.io/<YOUR_API_KEY>");

© www.soinside.com 2019 - 2024. All rights reserved.