0
0
Blockchain / Solidityprogramming~20 mins

Listening to events on frontend in Blockchain / Solidity - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Event Listener Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output when listening to a simple event?

Consider the following code snippet that listens to a blockchain event using ethers.js. What will be logged to the console when the event is emitted with value 42?

Blockchain / Solidity
const { ethers } = require('ethers');

const provider = new ethers.providers.JsonRpcProvider();
const contractAddress = '0x1234567890abcdef1234567890abcdef12345678';
const abi = [
  'event ValueChanged(uint256 newValue)'
];

const contract = new ethers.Contract(contractAddress, abi, provider);

contract.on('ValueChanged', (newValue) => {
  console.log(`New value is: ${newValue.toString()}`);
});

// Assume event ValueChanged(42) is emitted by the contract
ANew value is: 42
BTypeError: newValue.toString is not a function
CNew value is: undefined
DNew value is: 0x2a
Attempts:
2 left
💡 Hint

Remember that ethers.js BigNumber objects have a toString() method to convert to readable strings.

Predict Output
intermediate
2:00remaining
What happens if you forget to remove an event listener?

Given the following code, what will be the output after emitting the event twice?

Blockchain / Solidity
const { ethers } = require('ethers');

const provider = new ethers.providers.JsonRpcProvider();
const contractAddress = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd';
const abi = [
  'event DataUpdated(string data)'
];

const contract = new ethers.Contract(contractAddress, abi, provider);

function onDataUpdated(data) {
  console.log(`Data updated: ${data}`);
}

contract.on('DataUpdated', onDataUpdated);

// Event DataUpdated('First') emitted
// Event DataUpdated('Second') emitted
A
Data updated: First
Data updated: First
B
Data updated: First
Data updated: Second
Data updated: Second
C
Data updated: First
Data updated: Second
DNo output because listener is not removed
Attempts:
2 left
💡 Hint

Think about how many times the listener is attached and if it is removed.

🔧 Debug
advanced
2:00remaining
Why does this event listener not log anything?

Look at the code below. The event Transfer is emitted on the contract, but the console never logs anything. What is the reason?

Blockchain / Solidity
const { ethers } = require('ethers');

const provider = new ethers.providers.JsonRpcProvider();
const contractAddress = '0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed';
const abi = [
  'event Transfer(address indexed from, address indexed to, uint256 value)'
];

const contract = new ethers.Contract(contractAddress, abi, provider);

contract.on('transfer', (from, to, value) => {
  console.log(`Transfer from ${from} to ${to} of ${value.toString()}`);
});
ANo output because the event is not indexed
BNo output because event name is case-sensitive and should be 'Transfer' not 'transfer'
CNo output because the callback parameters are in wrong order
DNo output because the provider is not connected to the right network
Attempts:
2 left
💡 Hint

Check the event name spelling and capitalization.

📝 Syntax
advanced
2:00remaining
Which option correctly listens to multiple events with one callback?

You want to listen to both Deposit and Withdrawal events from a contract and log their details with one function. Which code snippet is correct?

Acontract.on('Deposit', (amount) => { console.log(amount); }); else contract.on('Withdrawal', (amount) => { console.log(amount); });
Bcontract.on('Deposit' || 'Withdrawal', (amount) => { console.log(amount); });
Ccontract.on(['Deposit', 'Withdrawal'], (event) => { console.log(event); });
D
contract.on('Deposit', (amount) => { console.log(amount); });
contract.on('Withdrawal', (amount) => { console.log(amount); });
Attempts:
2 left
💡 Hint

Think about how to attach multiple listeners properly.

🚀 Application
expert
3:00remaining
How to update UI state on event emission in React frontend?

You have a React app that listens to a blockchain event BalanceChanged. You want to update the displayed balance whenever the event fires. Which approach correctly updates the React state?

Blockchain / Solidity
import React, { useEffect, useState } from 'react';
import { ethers } from 'ethers';

const contractAddress = '0xabcabcabcabcabcabcabcabcabcabcabcabcabca';
const abi = [
  'event BalanceChanged(address indexed user, uint256 newBalance)'
];

export default function Balance() {
  const [balance, setBalance] = useState('0');

  useEffect(() => {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const contract = new ethers.Contract(contractAddress, abi, provider);

    // Fill in event listener here

    return () => {
      // Clean up listener
    };
  }, []);

  return <div>Balance: {balance}</div>;
}
A
contract.on('BalanceChanged', (user, newBalance) =&gt; {
  setBalance(newBalance.toString());
});

return () =&gt; {
  contract.off('BalanceChanged');
};
B
contract.on('BalanceChanged', (user, newBalance) =&gt; {
  setBalance(newBalance);
});

return () =&gt; {
  contract.off('BalanceChanged');
};
C
contract.on('BalanceChanged', (user, newBalance) =&gt; {
  balance = newBalance.toString();
});

return () =&gt; {
  contract.removeListener('BalanceChanged');
};
D
contract.on('BalanceChanged', (user, newBalance) =&gt; {
  setBalance(parseInt(newBalance));
});

return () =&gt; {
  contract.off('BalanceChanged');
};
Attempts:
2 left
💡 Hint

Remember to use the React state setter and convert BigNumber to string.