Understanding Web3 Events

Parv Garg
3 min readDec 6, 2020

--

Introduction

Trust me I have spent a lot of time trying to figure out how to listen/get events emitted by a smart contract. Now when I finally understand how to do this, I would like to share it with you.

In this article, we will understand how web3 can help us to read solidity smart contract events. Web3 provides various functions to get events from a smart contract. For understanding the functions easily, we will use the Transfer events emitted by the Tether USD contract.

To completely understand this article, you need to have some prior knowledge of smart contracts and web3.

Initial setup of Web3 Environment in Node.js

If you don’t wish to follow along you can skip this section.

Steps to setup-

  1. Create a new folder on your system
  2. Open this folder in your terminal
  3. Set up an empty node package manager by typingnpm init -y in your terminal.
  4. Create a file where all the code will be written, web3EventInteraction.js
  5. Install web3 library using the commandnpm i web3 in your terminal and then require it in our file const Web3 = require("web3")
  6. To interact with a contract you need its ABI and address. In this case, we need Tether USD’s ABI and address. To get this information, head over to this page, copy the ABI and address and assign it to a variable in web3EventInteraction.js
  7. We need one more essential thing to establish a connection with Ethereum Blockchain. For this, we will use Infura. Head over to Infura.io, create an account and then a project. Completing this you will have access to Infura Endpoints, which will allow web3 to communicate with Ethereum Blockchain. Now copy your Mainnet wss key and save it in a variable. Although it is recommended to store this in an environment file.
  8. Now create a web3 instance using const web3 = new Web3(infuraWss)
  9. At last, create a contract instance by const contractInstance = new web3.eth.Contract(tokenABI, tokenAddress)

And with this, we have completed our initial setup.

1. once

The once function of web3 subscribes for just one future event and unsubscribe after a successful event or error. Let us see how to use it.

.once function example

This returns an output like

{
removed: false,
logIndex: 22,
transactionIndex: 7,
transactionHash: '0x29a5956703074b015e75e6a9d41b3278b8ade7608621be64685f62c18efdc510',
blockHash: '0x890ae8ebcee90ca580f4915068e0c4880a8296f38b5677d0a8ce9e7d2ed101d2',
blockNumber: 11398118,
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
id: 'log_76bb9576',
returnValues: Result {
'0': '0xea1c9b9799CF4ff42738F62a226DA590354A3F1e',
'1': '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852',
'2': '600000000',
from: '0xea1c9b9799CF4ff42738F62a226DA590354A3F1e',
to: '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852',
value: '600000000'
},
event: 'Transfer',
signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
raw: {
data: '0x0000000000000000000000000000000000000000000000000000000023c34600',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000ea1c9b9799cf4ff42738f62a226da590354a3f1e',
'0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852'
]
}
}

2. events

The events function subscribes to an event, and as we know subscribe means listening to future events. Unlike once, events function keeps listening for events until stopped. Let us see how to use it.

.events web3 function

This returns and keeps returning 😅, output like this

Listening Transfer events
{
removed: false,
logIndex: 6,
transactionIndex: 30,
transactionHash: '0xa523744218743ccf68a16cb2a571c4df351c7321fa365a07cd50fc738610bd26',
blockHash: '0xd05db5c802c0602d4c545f19c424b76eddd539a70126a1ccd4ade12b32d41fec',
blockNumber: 11398469,
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
id: 'log_308d6122',
returnValues: Result {
'0': '0xa7503F592FEa15F094069de68f38A08E36058d41',
'1': '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852',
'2': '1982475198',
from: '0xa7503F592FEa15F094069de68f38A08E36058d41',
to: '0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852',
value: '1982475198'
},
event: 'Transfer',
signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
raw: {
data: '0x00000000000000000000000000000000000000000000000000000000762a2bbe',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000a7503f592fea15f094069de68f38a08e36058d41',
'0x0000000000000000000000000d4a11d5eeaac28ec3f61d100daf4d40471f1852'
]
}
}
...

3. getPastEvents

The getPastEvents function is very simple, unlike the previous functions which listen for future events, this returns all the previous events raised. Let us see how to use this.

.getPastEvents web3 function

This returns output like this

Returns all the past events
[
{
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
blockHash: '0x979197b08d5eb4bb69744abe32cb76bccf7a57480f23401dfd0d45283c54ae34',
blockNumber: 11398497,
logIndex: 29,
removed: false,
transactionHash: '0xdbff85e6be3759d6337238fe71c1d43f68b6fda1ae6340c05e8e338642c3db21',
transactionIndex: 29,
id: 'log_ea2d4591',
returnValues: Result {
'0': '0x0796c90B6813eD7F41a004729F3f6bD8774a20E1',
'1': '0xc19D0c4c7Ef8825d3d2A1610B93f33cBa0dCa959',
'2': '201000000',
from: '0x0796c90B6813eD7F41a004729F3f6bD8774a20E1',
to: '0xc19D0c4c7Ef8825d3d2A1610B93f33cBa0dCa959',
value: '201000000'
},
event: 'Transfer',
signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
raw: {
data: '0x000000000000000000000000000000000000000000000000000000000bfb0440',
topics: [Array]
}
},
{
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
blockHash: '0x979197b08d5eb4bb69744abe32cb76bccf7a57480f23401dfd0d45283c54ae34',
blockNumber: 11398497,
logIndex: 30,
removed: false,
transactionHash: '0x33118f0c63eda1fe6e2b47d6c07996492e3da4ea9ab3ad3d33ce94c357e95126',
transactionIndex: 30,
id: 'log_87ad0b0a',
returnValues: Result {
'0': '0x8874B9842178f15EB039Ddf5a861C9cD160A907C',
'1': '0x94c40659F1D2adb598cCE9100b0F7D384B11c152',
'2': '5000000000',
from: '0x8874B9842178f15EB039Ddf5a861C9cD160A907C',
to: '0x94c40659F1D2adb598cCE9100b0F7D384B11c152',
value: '5000000000'
},
event: 'Transfer',
signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
raw: {
data: '0x000000000000000000000000000000000000000000000000000000012a05f200',
topics: [Array]
}
}
...

Conclusion

To summarise, web3 offers three functions to interact with smart contract events- once, events, getPastEvents. The once function listens for just one future event. Similar to once, events listen to future events but does not stop automatically, it keeps listening. And getPastEvents unlike the previous two functions do not subscribe for future events but returns all the past events.

All the functions and setup used in this article can be found here.

Thanks for your time. Claps 👏🏻 are appreciated.

--

--

Parv Garg
Parv Garg

Written by Parv Garg

Ethereum Blockchain Developer | Somish Blockchain Labs | ICFAI Tech B.Tech