2

当在合同中触发事件(某事)时,页面控制台会按预期记录输出(通过 somethingEvent.watch()),但是当我重新加载页面时,它会在控制台中记录相同的输出。最近的事件是要持续存在还是我没有正确使用它?谢谢。

// Solidity
event Something(string message);

function doSomething(string newMessage) payable {
    Something(newMessage);
}

// Web3
var somethingEvent = contractInstance.Something();

somethingEvent.watch(function(error, result) {
  console.log(result.args.message);
});
4

1 回答 1

4

每当您调用watch()并且最新的块号与之前的执行相同时,都会发生这种情况。当一个事件被“触发”时,EVM 所做的就是在成功挖掘事务后将事件信息写入日志。

当您将监视添加到合约时,您可以指定要开始监听的块。如果您不传递任何内容(正如您的代码所做的那样),它默认为最新块(请参阅过滤器 API 文档)。因此,当您重新加载页面并且尚未将新块添加到链中时,您将获得相同的事件。

如果您想避免重复事件,请使用result.blockNumber记住最后读取的块,并在建立新手表时将其递增 1。

let blockNumber = 'latest'; // should come from some state initially set to 'latest'

...

var somethingEvent = contractInstance.Something({}, {fromBlock: blockNumber);

somethingEvent.watch(function(error, result) {
  blockNumber = result.blockNumber + 1;
  console.log(result.args.message);
});

请注意,watch在这种情况下,这可能不是最好的选择。这取决于您的客户端的状态。stopWatching每当您完成监听事件时,您应该始终调用。如果您不想设置手表,您还可以使用getwhich 将发送回所有符合您的过滤条件的事件。

于 2018-01-20T23:34:00.357 回答