Back to homepage

How to emit and capture events in Solidity

Published

Events to interact with decentralized web apps

Solidity smart contracts can emit 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) can listen to these events and take actions when they happen.

If you've used a decentralized exchange (or DEX) like Uniswap 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 a 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:

  // declare an event that sends two parameters
  event LotteryEvent(bool isWinner, address indexed player);

In the event definition you can also indicate if any of the parameters will be indexed with the indexed keyword. Indexed parameters can be used to filter event logs.

To emit or send 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:

  uint256 secretNumber = 99;

  function playLottery(uint256 _number) public {
    if(_number != secretNumber){
      // send the event
      emit LotteryEvent(false, msg.sender);
    }else{
      // send the event
      emit LotteryEvent(true, msg.sender);

    }
  }

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;

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, address indexed player);

  //
  function guessNumber(uint256 _number) public payable {

    if (_number != secretNumber) {
        // EVENT
        emit LotteryEvent(false, msg.sender);
    }else{
      // EVENT
      emit LotteryEvent(true, msg.sender);
    }


  }
}

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 (event) {
  console.log(`Result is ${event}`);
});

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 allow your smart contract to notify clients and other interested parties that something has happened in the blockchain. They are a very important tool in smart contract developement so make sure to use them wisely!

TAGS

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

Buy Me A Coffee