4

I am new to the world of web3 and trying to learn how to listen for events. I've been googling and reading for a while and can't seem to get something working. I'm able to subscribe to pendingTransactions and newBlockHeader but can't seem to get logs to work. Below is the closest I have gotten.

Right now the goal is to listen for logs at a specific address. Any help would be appreciated and an answer leading to a solution will garner an award.

const Web3 = require('web3');

const web3 = new Web3(new Web3.providers.WebsocketProvider('wss://mainnet.infura.io/ws'));
var subscription = web3.eth.subscribe('logs', {
    address: '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
    fromBlock : 7500000,
}, function (error, result) {
    if (!error)
        console.log(result);
})
    .on("data", function (log) {
        console.log(log);
    })
    .on("changed", function (log) {
    });

// unsubscribes the subscription
subscription.unsubscribe(function (error, success) {
    if (success)
        console.log('Successfully unsubscribed!');
});

returns: (node:17575) UnhandledPromiseRejectionWarning: Error: Provider error: Subscription with ID null does not exist.

3 Answers 3

1

In the code you provided, you create the subscription, then immediately try to unsubscribe and get an exception. More than likely that's because an async process in the form of a promise hadn't completed, and when it did, you'd already unsubscribed.

Regardless, that's not what you really want to do anyway. You want to subscribe and get some data, right?

So, if you remove that subscription.unsubscribe block and run it, you'll get something like the following:

Error: Node error: {"code":-32005,"message":"query returned more than 10000 results"}
at Function.validate (/Users/cliff/Documents/web3-subscribe/node_modules/web3-providers/dist/web3-providers.cjs.js:114:18)

This is coming from your callback. It's telling you you got beaucoup results; too many actually. Etherscan tells me that block was mined:

87 days 16 hrs ago (Apr-04-2019 06:08:57 AM +UTC)

So, let's pick a fresher block. I see that 8060000 was mined just:

7 hrs 39 mins ago (Jun-30-2019 03:19:12 PM +UTC)

So I drop that into the fromBlock option and voila:

{ address: '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
  blockHash: '0x85f9ddae65c8ccbff59585ad59ac6b0c753d2481eb9af8cd1a4f1a2c85ab7aaf',
  blockNumber: 8060013,
  data: '0x000000000000000000000000a8b39829ce2246f89b31c013b8cde15506fb9a76',
  logIndex: 107,
  removed: false,
  topics: 
   [ '0x91b01baeee3a24b590d112613814d86801005c7ef9353e7fc1eaeaf33ccf83b0' ],
  transactionHash: '0xe1f20cdc9a64c695b76cf0f5ae9440a41c451c89d7d387866a70d24aeeaab821',
  transactionIndex: 141,
  id: 'log_0x17ed98b92ffa29cf131111e89823af125901166111d43417507d4e101e08153b' }
{ address: '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
  blockHash: '0x85f9ddae65c8ccbff59585ad59ac6b0c753d2481eb9af8cd1a4f1a2c85ab7aaf',
  blockNumber: 8060013,
  data: '0x000000000000000000000000a8b39829ce2246f89b31c013b8cde15506fb9a76',
  logIndex: 107,
  removed: false,
  topics: 
   [ '0x91b01baeee3a24b590d112613814d86801005c7ef9353e7fc1eaeaf33ccf83b0' ],
  transactionHash: '0xe1f20cdc9a64c695b76cf0f5ae9440a41c451c89d7d387866a70d24aeeaab821',
  transactionIndex: 141,
  id: 'log_0x17ed98b92ffa29cf131111e89823af125901166111d43417507d4e101e08153b' }

.
.
.

{ address: '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
  blockHash: '0x59f6e3509b5ce466db760266342b742ad76f049081e5eb0a1a7db96de4b8ed19',
  blockNumber: 8062016,
  data: '0x2f1fb51f7edffae129489b1a765aab19877c9282615f8e792bb87726b8097a2a0000000000000000000000000ece224fbc24d40b446c6a94a142dc41fae76f2d',
  logIndex: 34,
  removed: false,
  topics: 
   [ '0xab38cdc4a831ebe6542bf277d36b65dbc5c66a4d03ec6cf56ac38de05dc30098',
     '0x00000000000000000000000071f35825a3b1528859dfa1a64b24242bc0d12990' ],
  transactionHash: '0x9cfd31b7e57843365664e9841daaaa3d841b073a686dd94d1a171abc2ad62d26',
  transactionIndex: 11,
  id: 'log_0x5a6e7afc1511be62f321d2af5663aea42321e33253c1f3a49f1d693a085558c8' }
{ address: '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
  blockHash: '0x59f6e3509b5ce466db760266342b742ad76f049081e5eb0a1a7db96de4b8ed19',
  blockNumber: 8062016,
  data: '0x2f1fb51f7edffae129489b1a765aab19877c9282615f8e792bb87726b8097a2a0000000000000000000000000ece224fbc24d40b446c6a94a142dc41fae76f2d',
  logIndex: 34,
  removed: false,
  topics: 
   [ '0xab38cdc4a831ebe6542bf277d36b65dbc5c66a4d03ec6cf56ac38de05dc30098',
     '0x00000000000000000000000071f35825a3b1528859dfa1a64b24242bc0d12990' ],
  transactionHash: '0x9cfd31b7e57843365664e9841daaaa3d841b073a686dd94d1a171abc2ad62d26',
  transactionIndex: 11,
  id: 'log_0x5a6e7afc1511be62f321d2af5663aea42321e33253c1f3a49f1d693a085558c8' }
1

Dev Advocate at Chainstack here.

In case anyone needs an updated answer to Web3.js V4.

To listen for events at a specific contract using web3.js, you can use the web3.eth.subscribe('logs', {...}) method — Check the docs: web3js subscribe.

This method allows you to subscribe to real-time updates about new event logs on the Ethereum blockchain. Your application will receive notifications whenever new logs matching the specified filter are emitted.

Here's an example of how you can use web3.eth.subscribe('logs', {...}) to listen for events at a specific contract address.

This example listens for the Transfer event from the WETH smart contracts.

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

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

// Filter for WETH transfer events
const logsFilter = {
    address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH contract address
    topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'] // Transfer event signature
};

async function subscribeToLogs() {
  try {
    // Create a new subscription to logs with the specified filter
    const subscription = await web3.eth.subscribe('logs', logsFilter);

    console.log(`Subscription created with ID: ${subscription.id}`);

    // Attach event listeners to the subscription object for 'data' and 'error'
    subscription.on("data", handleLogs);
    subscription.on("error", handleError);
  } catch (error) {
    console.error(`Error subscribing to new logs: ${error}`);
  }
}

// Event listener that logs the received log data
function handleLogs(log) {
  console.log("New log received:", log);
}

// Event listener that logs any errors that occur
function handleError(error) {
  console.error("Error when subscribing to new logs:", error);
}

subscribeToLogs();

In this example, we first connect to a WebSocket provider, which is required for subscriptions in web3.js. Then, we define the filter options, specifying the contract address we want to watch and the block number from which to start watching.

// Filter for WETH transfer events
const logsFilter = {
    address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH contract address
    topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'] // Transfer event signature
};

You can learn about the encoding of the topics from this recipe: How to properly encode topics for eth_getLogs or convert using the Chainstack EVM Knife

Next, we subscribe to the 'logs' event using web3.eth.subscribe('logs', filterOptions, callback). The callback function will be called for each new log matching the filter, and we can handle any errors during the subscription process.

We also attach event listeners to the subscription object using .on('data', ...) and .on('error', ...). The 'data' event handler will be called for each new log matching the filter, and the 'error' event handler will be called if any errors occur during the subscription.

Note that the subscribe('logs', ...) method requires a WebSocket connection, so we use the new Web3.providers.WebsocketProvider(...) provider in this example.

If you want to fetch past logs instead of real-time events, then you can use eth_getLogs.

0

You can use the following query to listen to all events for smart contracts.

https://ide.bitquery.io/USDT-smart-contract-events-on-ethereum

In this, we get all the events of the USDT smart contract.

You can use any other smart contract address for the event.

In case it's a proxy contract, then use Logheader.

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.