在 Web3j 中监听事件

Posted

技术标签:

【中文标题】在 Web3j 中监听事件【英文标题】:Listening to events in Web3j 【发布时间】:2017-10-28 17:22:17 【问题描述】:

我正在修补 web3j,我想做的大部分事情都成功了,但是我似乎无法收听事件。

我通过添加一个事件 VoteEnded 扩展了您通过 remix 获得的 ballot.sol 合约,该事件在调用 winsProposal 时触发,并且在 Remix javascript VM 中有效。

...
event VoteEnded();
...

function winningProposal() constant returns (uint8 winningProposal) 
    uint256 winningVoteCount = 0;
    for (uint8 proposal = 0; proposal < proposals.length; proposal++)
        if (proposals[proposal].voteCount > winningVoteCount) 
            winningVoteCount = proposals[proposal].voteCount;
            winningProposal = proposal;
        
    VoteEnded();

...

我能够在 Web3j 中部署此合约并进行投票等。然后我添加了一个过滤器来收听 VoteEnded。我是这样做的:

    EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, contract.getContractAddress());
    web3.ethLogObservable(filter).subscribe(new Action1<Log>() 
        @Override    
        public void call(Log log) 
            System.out.println("log.toString(): " +  log.toString());
        
    );

然而这根本不打印任何东西。

我做错了什么?

【问题讨论】:

【参考方案1】:

您需要添加filter.addSingleTopic(EventEncoder.encode(event)),其中event 是一个实例化的org.web3j.abi.datatypes.Event 对象。

【讨论】:

【参考方案2】:

当收听 基于本地松露的节点时,我必须添加 .substring(2):

EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, contract.getContractAddress().substring(2);

其次,你可能需要使用

    String encodedEventSignature = EventEncoder.encode(event);
    filter.addSingleTopic(encodedEventSignature);

在您的情况下,事件应该是什么样子的

new Event("VoteEnded", 
            Arrays.<TypeReference<?>>asList(), Arrays.<TypeReference<?>>asList());

【讨论】:

以上是关于在 Web3j 中监听事件的主要内容,如果未能解决你的问题,请参考以下文章

ios里面怎样监听js的事件

在android中怎样给整个页面设置监听事件

Spring事件监听机制源码解析

js中监听iframe点击事件

Mac 鼠标/键盘事件的监听和模拟

java 事件监听