- 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
anonymousevents). - 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 withemit; 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.
The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.
Question / Answer (15 questions)
event Deposited(address indexed from, uint amount);, and trigger it inside a function with emit Deposited(msg.sender, msg.value);.contract.getPastEvents('EventName', { filter, fromBlock, toBlock }), which returns matching events and their returnValues.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.
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.
- 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
- ethereum.org. (n.d.). Smart contract anatomy (events and logs). Ethereum Developer Documentation. https://ethereum.org/en/developers/docs/smart-contracts/anatomy/
- ChainSafe Systems. (n.d.). Web3.js Documentation. https://docs.web3js.org/
- Solidity Team. (n.d.). Contract ABI Specification. Solidity Documentation. https://docs.soliditylang.org/en/latest/abi-spec.html
- 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.