1

I am trying to read events issued on my hardhat local node.

My code is the following

var fs = require('fs');
var jsonFile = "artifacts/contracts/STPOAP_ERC.sol/STPOAP_ERC.json";
var parsed= JSON.parse(fs.readFileSync(jsonFile));
var abi = parsed.abi;
//console.log(abi)

const { Web3 } = require('web3');
const web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");
//var Contract = require('web3-eth-contract');

var myContract = new web3.eth.Contract(abi, '0x5FbDB2315678afecb367f032d93F642f64180aa3', {
  from: '0x5FbDB2315678afecb367f032d93F642f64180aa3', // default from address: the same as the smartcontract address?
  gasPrice: '20000000000' // default gas price in wei, 20 gwei in this case
});

 

async function main() {
  
    console.log(await myContract.events.tokenReceived({
      filter: {test: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"}, // Using an array means OR: e.g. 20 or 23
      fromBlock: 0
  }, function(error, event){ console.log(event); }))
  .on('data', function(event){
      console.log(event); // same results as the optional callback above
  })
  .on('changed', function(event){
      // remove event from local database
  })
  .on('error', console.error);
  
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

When I execute the function, I receive the following error:

Cannot read properties of undefined (reading 'on')

Trying to debug this since many hours. does someone see the mistake?

Thx

2 Answers 2

3

Dev Advocate at Chainstack here.

I think you might be mixing up event logs with the events emitted by web3.js when sending a transaction, like in this case, deploying a smart contract.

Please correct me if my assumption is wrong here!

It looks like you need to listen to events emitted by a smart contract, but the Contract.events. method in this case, is to catch events emitted by the transaction itself.

You can find the source code in Web3.js contracts.ts file. As you can see here, the events emitted are:

     sendObject.on('transactionHash', function(hash){
       ...
     });
     sendObject.on('receipt', function(receipt){
       ...
     });
     sendObject.on('confirmation', function(confirmationNumber, receipt){
       ...
     });
     sendObject.on('error', function(error, receipt) {
       ...
     });

This means that you can extract this kind of data, for example, get the transaction hash immediately after the transaction is sent with sendObject.on('transactionHash', function(hash), or wait for the receipt or the confirmation.

If you want to listen for event emitted by a smart contract, you have a couple of options:

Real-time events

To listen for events in real time, you can use a WSS endpoint and subscriptions. Here is an example to listen for Transfer events on the WETH contract.

const { Web3 } = require("web3");

const NODE_URL =
  "YOUR_WSS_URL";
const web3 = new Web3(NODE_URL);

// Only log transfer events from the WETH smart contract.
const logsFilter = {
  address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // Contract address
  topics: [
    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", // Event signature
  ],
};

async function subscribeToLogs() {
  try {
    // Create a new subscription to the 'logs' event with the specified filter
    const subscription = await web3.eth.subscribe("logs", logsFilter);
    console.log(`Subscription ID: ${subscription.id}`);
    // Attach event listeners to the subscription object
    subscription.on("data", handleLogs);
    subscription.on("error", handleError);
  } catch (error) {
    console.error(`Error subscribing to new logs: ${error}`);
  }
}

// Fallback functions to react to the different events

// Event listener that logs the filtered events
function handleLogs(log) {
  console.log("Received log:", log);
}

// Event listener that logs any errors that occur
function handleError(error) {
  console.error(`Error with log subscription: ${error}`);
}

subscribeToLogs();

You have a couple options to get the event signature:

function encodeEvent(event) {
  const keccakHash = Web3.utils.keccak256Wrapper(event);
  return keccakHash;
}

const eventToEncode = "Transfer(address,address,uint256)";
const signature = encodeEvent(eventToEncode);
console.log(signature);

Past events

If you want to fetch past events, then you can use the getPastEvents method, which looks like you are trying to use in this case.

This example gets the past Tranfer events of WETH to this specific address 0xBa0E5766E74A3dCa446Fd4a7724808b468BBB176.

This is how the event looks like in the WETH contract:

event  Transfer(address indexed src, address indexed dst, uint wad);

So, in this case we fitler for the dst parameter.

async function main() {
  const contract = new web3.eth.Contract(
    abi,
    "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
  );

  const events = await contract.getPastEvents("Transfer", {
    filter: {
      //src: ["0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"],
      dst: ["0xBa0E5766E74A3dCa446Fd4a7724808b468BBB176"],
    },
    fromBlock: 18763643n,
    toBlock: "latest",
  });

  console.log(events);
}

main().catch(console.error);

Based on your code snippet, you could do it like this


  const events = await contract.getPastEvents("tokenReceived", {
    filter: {
      test: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"],
    },
    fromBlock: 0,
    toBlock: "latest",
  });

  console.log(events);
}

main().catch(console.error);

Note that where it has test you need to add the indexed event parameter you are looking for, unless the parameter is named test.

You can learn more about listening to real-time events here:

Please note that those examples are using [email protected], I'm working on updating the code examples to the new version 4!

Feel free to reach out if you need help.

2
  • 1
    Thank you Sir! It works perfectly. I really appreciate your help! You saved my day!
    – PupSt4r
    Commented Dec 12, 2023 at 6:03
  • Awsome, Anytime ser! Commented Dec 13, 2023 at 12:46
0

await Contract.methods.Deposit().send({from:account, value: web3.utils.toWei(Amount, "ether")}) .then(receipt =>{ console.log("receipt is:",receipt.events.deposit.event) alert(Amount + " Ether Deposit In Your Account") getBalance() setAmount('') })

New contributor
Satnam Singh is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

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

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