Events in Solidity: define, emit and listen

Events in Solidity are used to log that something happened in our contract and they can also be used to pass data to the front-end of the application. Data passed to an event is stored on the blockchain but can not be retrieved by the smart contract. The Ethereum Virtual Machine (EVM) stores events on the blockchain in transaction logs (they are LOG opcodes). 

Events are inheritable members of contracts. When you call them, they cause the arguments to be stored in the transaction’s log — a special data structure in the blockchain. These logs are associated with the address of the contract, are incorporated into the blockchain, and stay there as long as a block is accessible
It is important to remember that all information stored on the blockchain is public, therefore no private information can be used. Events are similar to using console.log() in JavaScript or the print() function in Python.

Why use Events?

A common use case is to document different stages of our smart contract. For example, if we run an auction via the contract, we can use Events to keep track of the highest bidder. We just have to log all the bids via an event. We can also send updates about the auction via the web front-end or the mobile app to bidders, so they can place a new bid when they have been outbid. In the same way, a decentralized exchange can inform users via the UI or an API about new trades or changes to the order book. Events can be also useful to debug a smart contract. When it comes to gas costs, it is much cheaper to store data in the event logs. However, it's not possible to retrieve the data by the smart contract and therefore it can only be used for data that is shown in the UI.

How to use events in Solidity?

We use events in Solidity usually in a three step process:
  1. Define events in the contract body
  2. call the event using the emit keyword
  3. listen to the event via remix or javascript

Define Events in Solidity

How to define events in Solidity? To define an event in Solidity we use the event keyword. In this example, we create an event named Log that will accept one input of data type address and one input of data type uint. The declaration of an event has to happen in the body of our smart contract. The best practice is to define the event before the functions are defined. event Log(address _from, uint _value); It is possible to use up to three indexed parameters in Solidity Events.

indexed Events

There are two types of parameters an event can use: unindexed and indexed inputs. To filter the logs we can define indexed inputs for our events. This is done using the indexed keyword. event Log(address indexed _from, uint _value); There is a limit on indexes: Only three parameters can be indexed in an Event. It is also important to understand that indexed parameters cost more gas than unindexed parameters. The reason is that an index has to be built and the gas costs for it are added to the execution costs.

Emit: How to call Events in Solidity?

The next step after our event is defined, is to call the event. This is done via the emit keyword within a function. In the example below, we pass the msg.sender and msg.value to log the address of the caller of our contract and the value. To use those transaction properties the function has to be payable. emit Log(msg.sender, msg.value); To better understand the whole concept of events in Solidity let's look at the complete code. The EventsExample contract contains the declaration of the event and the example() function that emits the event Test() when it is called. // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; // Events in Solidity contract EventsExample { // declare an event event Test(address _from, uint _value); // emit event function example() external payable { emit Test(msg.sender, msg.value); } }

listen to events

To see events and listen to the emitted events we have three options: 1. An IDE like Remix 2. An block explorer like Etherscan 3. An JavaScript library like Ether.js or web3.js In this tutorial, we will use the Remix IDE because it is the most beginner-friendly way. After we have compiled and deployed our smart contract, we can call the example function in the remix IDE. Remix changed the button to call the function to red because we have defined the function as payable. If we call the example function it emits our event and we can then listen to the transaction in Remix. This gives us all kinds of information like the status of the transaction, the hash, the gas cost, and more. Under logs, we can find the logged information our event emitted. In this example, the _from address and the _value. event log in remix IDE



Click to jump to section