Ethers.js – Dealing with Events in Ethers.js

ethers.jsjavascriptsolidity

I'm trying to get a better understanding of arbitrary bytes parameters, so I wrote a one-function smart contract that accepts a bytes argument, decodes it, and returns the response. I am having trouble calling the contract from a script using ethers.js – I get the correct response, but the script never ends. I have to add process.exit() – I'd like to know why the script isn't ending even though the promise is resolved, and how I should appropriately be handling events;

Here's my Solidity code:

pragma solidity ^0.5.0;
contract Byt {
  event bytDone (uint256 a, uint256 b);
  function takeByt(bytes memory byt) public returns (uint256, uint256) {
    (uint256 a, uint256 b) = abi.decode (
      byt,
      (uint256, uint256));
    emit bytDone(a, b);
    return (a, b);
  }
}

and here's where I'm trying to call the function from javascript with test values of 10 and 15:

let num1 = 10;
let num2 = 15;
let byt = ethers.utils.defaultAbiCoder.encode(
  ['uint256', 'uint256'],
  [num1, num2]
);
bytesTest(byt);
async function bytesTest(byt){
  try{
    let c = await bytesContract.takeByt(byt, {gasLimit: 100000});
    let r = await bytesContract.on("bytDone", (res1, res2) => {
      console.log(res1);
      console.log(res2);
    });
  }catch(err){
    console.log(err);
  }
}

The output is:

BigNumber { _hex: '0x0a' }
BigNumber { _hex: '0x0f' }

These are the appropriate hex encodings of 10 and 15 respectively, meaning I've picked up the event after correctly calling the solidity function. This is supposed to be the "await" part of my javascript code. The problem is, the script doesn't end – after console.logging res1 and res2 – it seems to just be waiting for something else. If anyone could explain why the script isn't ending, and what I should do to appropriately handle the emitted event from my solidity contract, I'd be forever grateful. Thanks in advance for your help!

Best Answer

I had the same issue and using once for events filtering also didn't work. I had to stop provider from polling events.

You can do it like this:

bytesContract.provider.polling = false

This is what ethers documentation says about it

prototype.polling mutable

If the provider is currently polling because it is actively watching for events. This may be set to enable/disable polling temporarily or disabled permanently to allow a node process to exit.

Ethers Provider Polling Documentation

Worked for me. New provider has polling set to false and only when you filter for events or call transactions it will start polling.

Related Topic