使用 web3 的智能合约中的持久事件状态
Persistent event state in smart contract with web3
当合同中触发事件(某事)时,页面控制台按预期记录输出(通过 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);
});
只要你调用watch()
并且最新的块号与上一次执行相同,就会发生这种情况。当事件为 "fired" 时,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
这将发送回所有符合您过滤条件的事件。
当合同中触发事件(某事)时,页面控制台按预期记录输出(通过 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);
});
只要你调用watch()
并且最新的块号与上一次执行相同,就会发生这种情况。当事件为 "fired" 时,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
这将发送回所有符合您过滤条件的事件。