9

I have an event set up in the Contract.

Contact Packages
   emit Spend(msg.sender, msg);

   function sendPackage(msg) external payable returns(bool) {
     require(
       msg.value == price,
       'Please send the correct amount of ETH to make send a message'
     );

     emit Spend(msg.sender, msg);
     return true;
}

And a script in NodeJS that listens to new events.

The intention is to kick off some NodeJS code whenever a new event on the contract takes place.

But whenever I start the script, the Contract.on(.. fires and the last event is passed to it, even though the event fired a hour ago.

Is there a way to config the callback to NOT include previous events?

  Contract.on('Spend', (sender, event) => {
    console.log(sender);
    console.log(event);
  });

EDIT

I've tried to use Contact.once and the same result occurs.

1
  • 1
    Hey did you find a solution to this? I am facing the same problem. It always returns the last event no matter when it was fired. Apr 26, 2021 at 11:42

3 Answers 3

1

I don't know about ethers.js but you can use web3.js as follows

Create an instance of your contract

var contract = new web3.eth.Contract(ABI_of_contract, address_of_contract);

and then listen for new events

contract.events.Spend({
  fromBlock: 'latest'
  }, function(error, event){
      console.log(event);
  });

Note that fromBlock: 'latest' is needed to load only new events. If you use 'earliest' instead, you will get all past events as well (maybe there is such an option in ethers.js)

1

get the startblock number from provider

const startBlockNumber = await provider.getBlockNumber();

then check that with the blocknumber recieved from event.

Full code:

const startBlockNumber = await provider.getBlockNumber();
provider.once("block", () => {
    transactionsContract.on(
        "Transfer",
        (from, to, amount, timestamp, message, blockNumber) => {
            if (blockNumber <= startBlockNumber) {
                console.log("old event");
                return;
            }
            console.log({
                from,
                to,
                amount,
                timestamp,
                message,
                blockNumber,
            });
        }
    );
});
1

I do this:

const eventListener = async (blockNumber) => {
    try {
        const contractInstance = new ethers.Contract(address, ctt.abi, provider)
        const event = await contractIntance.queryFilter('EventName', blockNumber - blockNumberN, blockNumber);
        console.log(event);
    }
    catch (error) {
        console.log(error);
    }
};

wssProvider.on('block', async (blockNumber) => {
    await eventListener(blockNumber)
})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.