Learning Objectives – after this chapter you will be able to:
  • Declare and emit events.
  • Explain indexed parameters (topics) and where logs are stored.
  • Explain why events are cheaper than storage and what their limits are.
  • Listen to events from a Web3.js front end.
What are Events in Solidity?
  • Events are notifications that a contract sends out when something important happens – like a notification you receive when a channel uploads a new video.
  • When an event is emitted, its data is written to the transaction’s logs, which are stored in the transaction receipt on the blockchain.
  • Front ends, back-end services and block explorers read these logs to react to contract activity.
  • Logs are not accessible to smart contracts – a contract cannot read past events – which is one reason storing data in an event costs much less gas than storing it in a state variable.
Why Use Events?
  • Update the user interface – a dApp can show “Payment received” as soon as the event appears, instead of repeatedly reading the contract.
  • Transaction status – users can see the progress and result of their transactions.
  • History and auditing – every emitted event remains in the blockchain history, so actions can be tracked later.
  • Cheap data storage – data needed only off-chain can be logged instead of stored.
How to Use Events in Solidity

1. Declaring an event – use the keyword event, then the event name and its parameters in brackets:

event Deposited(address indexed from, uint amount);

2. Emitting an event – inside a function, use emit, the event name and the values:

emit Deposited(msg.sender, msg.value);

3. Parameters – two kinds can be passed to an event:

  • Indexed parameters – stored as searchable topics, so applications can filter events (e.g. “all deposits from this address”). Up to three parameters can be indexed (four for anonymous events).
  • Non-indexed parameters – stored in the data part of the log; they are returned with the event but cannot be used as filters.
Example : Contract with Events
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract PiggyBank {
    address public owner;

    event Deposited(address indexed from, uint amount);
    event Withdrawn(address indexed to, uint amount);
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    constructor() {
        owner = msg.sender;
    }

    function deposit() external payable {
        require(msg.value > 0, "Send some Ether");
        emit Deposited(msg.sender, msg.value);
    }

    function withdraw(uint amount) external {
        require(msg.sender == owner, "Only owner");
        require(amount <= address(this).balance, "Not enough balance");
        (bool ok, ) = payable(owner).call{value: amount}("");
        require(ok, "Transfer failed");
        emit Withdrawn(owner, amount);
    }

    function changeOwner(address newOwner) external {
        require(msg.sender == owner, "Only owner");
        emit OwnerChanged(owner, newOwner);
        owner = newOwner;
    }
}
Listening to Events with Web3.js
// past events (e.g. all deposits from one address)
const events = await piggyBank.getPastEvents('Deposited', {
    filter: { from: userAddress },     // works because "from" is indexed
    fromBlock: 0, toBlock: 'latest'
});
events.forEach(e => console.log(e.returnValues.from, e.returnValues.amount));

Live subscriptions (contract.events.Deposited()) need a WebSocket provider. See the Web3.js course and Project 6.

Key Takeaways
  • Declare with event, trigger with emit; data goes to transaction logs.
  • Up to three indexed parameters become searchable topics.
  • Contracts cannot read logs, so events suit off-chain notifications and history, not on-chain logic.
Download | Print      E-Notes

The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.

Video : Events in Solidity
Resource File
Question / Answer (15 questions)

Answer : Events are notifications emitted by a contract when something important happens. Their data is written to the transaction’s logs on the blockchain, where front ends and services can read it.

Answer : Declare it with the event keyword, e.g. event Deposited(address indexed from, uint amount);, and trigger it inside a function with emit Deposited(msg.sender, msg.value);.

Answer : In the logs of the transaction receipt, which are part of the blockchain data. It is not stored in the contract’s storage.

Answer : No. Logs are not accessible to contracts; they are meant for off-chain applications.

Answer : Log data does not need to be kept in contract storage or be readable by contracts, so the gas cost per byte is much lower than writing to storage.

Answer : Event parameters marked indexed are stored as topics, which allows applications to search and filter events by those values, e.g. all deposits from a particular address.

Answer : Up to three for a normal event (four for an anonymous event).

Answer : Indexed parameters become searchable topics; non-indexed parameters are stored in the log’s data section and returned with the event but cannot be used as filters.

Answer : They update user interfaces in real time, show transaction status, provide a permanent history for auditing and tracking, and store off-chain-only data cheaply.

Answer : With contract.getPastEvents('EventName', { filter, fromBlock, toBlock }), which returns matching events and their returnValues.

Answer : Because contracts cannot read events; any data the contract itself needs for later decisions must be kept in storage.

Answer : So that applications can efficiently filter deposits made by a specific address.

Answer : No. When a transaction reverts, all its effects, including emitted events, are discarded.

Answer : An event declared with the anonymous keyword does not store its signature as the first topic, which allows four indexed parameters and saves some gas, but it cannot be filtered by event name.

Answer : A provider that supports subscriptions, usually a WebSocket provider; plain HTTP providers can only query past events.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Which keyword triggers an event?

Show Answer

Correct Answer : A. emit
emit EventName(args) triggers the event.

Q2. Event data is stored in:

Show Answer

Correct Answer : B. Transaction logs
Events are written to logs in the receipt.

Q3. Up to how many parameters of a normal event can be indexed?

Show Answer

Correct Answer : D. Three
Three indexed parameters (four if anonymous).

Q4. Which statement about events is TRUE?

Show Answer

Correct Answer : C. Contracts cannot read events
Logs are for off-chain consumers only.

Q5. Indexed event parameters are stored as:

Show Answer

Correct Answer : A. Topics
Indexed parameters become searchable topics.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Contracts (creating contracts, visibility and getters, function modifiers, constant and immutable, functions, events, custom errors, inheritance, abstract contracts, interfaces, libraries). Solidity Documentation. https://docs.soliditylang.org/en/latest/contracts.html
  2. ethereum.org. (n.d.). Smart contract anatomy (events and logs). Ethereum Developer Documentation. https://ethereum.org/en/developers/docs/smart-contracts/anatomy/
  3. ChainSafe Systems. (n.d.). Web3.js Documentation. https://docs.web3js.org/
  4. Solidity Team. (n.d.). Contract ABI Specification. Solidity Documentation. https://docs.soliditylang.org/en/latest/abi-spec.html
  5. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.