代码之家  ›  专栏  ›  技术社区  ›  totalnoob

web3智能合约中的持久事件状态

  •  2
  • totalnoob  · 技术社区  · 7 年前

    当合同中触发事件(某物)时,页面控制台会按预期记录输出(通过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);
    });
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Adam Kipnis    7 年前

    无论何时你打电话都会这样 watch() 并且最新的块编号与之前的执行相同。当一个事件被“触发”时,EVM所做的就是在成功挖掘事务后将事件信息写入日志。

    将手表添加到协定时,可以指定要开始侦听的块。如果没有传入任何内容(正如代码所做的),则默认为最新的块(请参见 filter API docs ). 因此,当您重新加载页面且链中未添加新块时,您将得到相同的事件。

    如果要避免重复事件,请使用 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 get 这将发回所有符合筛选条件的事件。