Back to homepage

How to emit and capture smart contract events

Published

Events to interact with decentralized web apps

Solidity smart contracts can trigger events to communicate that something has happened on the blockchain. Web applications or any kind of application (like a mobile app or a backend job) listen to these events and take action when they happen.

If you've used a decentralized exchange (or DEX) like SushiSwap or PancakeSwap, or any other web3 application, you've probably seen events in action in loading buttons and popup messages when transactions are confirmed. These are usually events triggered from smart contract and captured by the web application.

How to emit events from a smart contract

The first thing we need to do is to declare the event with the Event keyword. Events can send multiple parameters so we have to include these in the event definition (don't forget to include the type as well!). The event definition below will just have a boolean variable as payload:

  event LotteryEvent(bool isWinner);

To trigger an event from our smart contract, we'll use the emit keyword followed by the event name and the payload that it'll send. It's very similar to calling a function:

  emit LotteryEvent(false);

See below a full example of a very basic smart contract game. There is secret number stored in the contract and users would be able to guess it by calling the guessNumber() method. The contract will trigger an event whether they correctly guess the number or not.

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.4;

import "hardhat/console.sol";

contract LuckyNumber {
  // state variable to store secret number
  uint256 secretNumber;

  // set the secret number on deploy
  constructor() payable {
      secretNumber = 33;
      console.log("The secret number is %s", secretNumber);
  }
  // declare the event with the payload to send
  event LotteryEvent(bool isWinner);

  //
  function guessNumber(uint256 _number) public payable {

    if (_number != secretNumber) {
        console.log("Ohhhhh");
        // EVENT
        emit LotteryEvent(false);
    }

    console.log("Winner winner");
    // EVENT
    emit LotteryEvent(true);

  }
}

Capture events in web3 application

Once we have a smart contract that emit events, we can listen to them from a web3 application.

To interact with our smart contract from a web app, we'll need the contract address and the ABI. In the example below I'm using Metamask as a provider, and ethers.js to create a contract instance that points to my smart contract. On this instance we can use the on() method to handle the events:

// Contract information
const LuckyNumber = require('/artifacts/solidity/contracts/LuckyNumber.sol/LuckyNumber.json');
const contractAddress = '0xabc12345fecad67343434....';

const provider = new ethers.providers.Web3Provider(window.ethereum);

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

console.log('contract :>> ', contract);
// handle event from contract
contract.on('LotteryEvent', function (result) {
  console.log(`Result is ${result}`);
});

The on() method receives the event name and a callback function with the payload sent in the event. In the example above we're just printing it in the console but we can use this event to display a popup message, a notification or whatever we need in our web app.

Conclusion

Events are a very important tool in smart contract developement as they're used to broadcast that something has changed in the blockchain. Make sure to use them!

TAGS

If you enjoyed this article consider sharing it on social media or buying me a coffee ✌️

Buy Me A Coffee