📖 Scenario: You are building a simple web page that listens to blockchain events from a smart contract. When the contract emits an event, your page will show a message to the user.
🎯 Goal: Create a small frontend script that connects to a blockchain contract and listens for a specific event. When the event happens, display the event data on the page.
📋 What You'll Learn
Create a variable called contractAddress with the exact value '0x1234567890abcdef1234567890abcdef12345678'.
Create a variable called contractABI with the exact value [{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"NewMessage","type":"event"}].
Create a variable called provider using new ethers.providers.Web3Provider(window.ethereum).
Create a variable called contract using new ethers.Contract(contractAddress, contractABI, provider).
Use contract.on('NewMessage', (message) => { ... }) to listen to the event and update the page.
Display the event message inside the HTML element with id eventMessage.
💡 Why This Matters
🌍 Real World
Listening to blockchain events is essential for building interactive decentralized applications (dApps) that respond to changes on the blockchain in real time.
💼 Career
Frontend developers working with blockchain need to know how to connect to smart contracts and listen to events to create responsive user interfaces.
Progress0 / 4 steps
1
Set up contract address and ABI
Create a variable called contractAddress with the value '0x1234567890abcdef1234567890abcdef12345678'. Then create a variable called contractABI with the exact event ABI array: [{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"NewMessage","type":"event"}].
Blockchain / Solidity
Hint
Use const to create variables. The ABI is an array with one event object.
2
Create provider and contract instance
Create a variable called provider using new ethers.providers.Web3Provider(window.ethereum). Then create a variable called contract using new ethers.Contract(contractAddress, contractABI, provider).
Blockchain / Solidity
Hint
Use new ethers.providers.Web3Provider(window.ethereum) to create the provider. Then use new ethers.Contract() with the address, ABI, and provider.
3
Listen to the NewMessage event
Use contract.on('NewMessage', (message) => { ... }) to listen to the event. Inside the callback, update the text content of the HTML element with id eventMessage to the message received.
Blockchain / Solidity
Hint
Use contract.on to listen. Use document.getElementById('eventMessage').textContent = message to show the message.
4
Display the event message on the page
Write a line to print the text content of the element with id eventMessage after the event is received. Use console.log to print the message from the element.
Blockchain / Solidity
Hint
Use console.log(document.getElementById('eventMessage').textContent) inside the event callback.
Practice
(1/5)
1. What is the main purpose of listening to blockchain events in a frontend application?
easy
A. To create new smart contracts
B. To send transactions to the blockchain
C. To react instantly when something changes on the blockchain
D. To mine new blocks on the blockchain
Solution
Step 1: Understand event listening in frontend
Listening to events means the app waits and reacts when blockchain data changes.
Step 2: Identify the purpose of event listening
The main goal is to update the app instantly when something happens on the blockchain.
Final Answer:
To react instantly when something changes on the blockchain -> Option C
Quick Check:
Listening to events = instant reaction [OK]
Hint: Events let your app update instantly on blockchain changes [OK]
Common Mistakes:
Confusing event listening with sending transactions
Thinking event listening creates contracts
Mixing event listening with mining blocks
2. Which of the following is the correct way to listen continuously to an event named Transfer using ethers.js?
easy
A. contract.once('Transfer', callback)
B. contract.watch('Transfer', callback)
C. contract.listen('Transfer', callback)
D. contract.on('Transfer', callback)
Solution
Step 1: Recall ethers.js event listening methods
Use contract.on to listen continuously to events.
Step 2: Match method to event name
For event 'Transfer', the syntax is contract.on('Transfer', callback).
Final Answer:
contract.on('Transfer', callback) -> Option D
Quick Check:
Continuous listening = contract.on [OK]
Hint: Use contract.on for continuous event listening [OK]
But your app never logs anything even though deposits happen. What is the most likely mistake?
medium
A. The event name 'Deposit' is misspelled or does not exist in ABI
B. You used contract.once instead of contract.on
C. You did not import ethers.js library
D. You forgot to connect the provider to the contract
Solution
Step 1: Check event name and ABI
If the event name is wrong or missing in ABI, the listener won't trigger.
Step 2: Verify other common issues
Provider connection and import errors usually cause runtime errors, not silent no logs.
Final Answer:
The event name 'Deposit' is misspelled or does not exist in ABI -> Option A
Quick Check:
Correct event name in ABI = logs appear [OK]
Hint: Check event name spelling and ABI matches [OK]
Common Mistakes:
Assuming contract.once listens continuously
Ignoring ABI event definitions
Not connecting provider causes errors, not silent failure
5. You want your frontend app to listen to a Transfer event but only react to transfers where the from address is your wallet address 0x123. Which approach correctly filters these events using ethers.js?
hard
A. contract.on('Transfer', { from: '0x123' }, callback)
B. contract.on('Transfer', (from, to, amount) => { if (from === '0x123') { /* react */ } })
C. contract.filter('Transfer').from('0x123').on(callback)
D. contract.once('Transfer', (from, to, amount) => { if (from === '0x123') { /* react */ } })
Solution
Step 1: Understand event filtering in ethers.js frontend
Direct filtering by event parameters in contract.on is not supported; filtering must be done inside the callback.
Step 2: Choose correct method to filter by 'from'
Use contract.on('Transfer', callback) and inside callback check if from === '0x123'.
Final Answer:
contract.on('Transfer', (from, to, amount) => { if (from === '0x123') { /* react */ } }) -> Option B
Quick Check:
Filter inside callback for specific addresses [OK]
Hint: Filter event data inside callback, not in contract.on params [OK]
Common Mistakes:
Trying to filter events by passing object to contract.on
Using contract.once for continuous filtering
Using non-existent filter chaining methods
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.