Logs help applications observe defined execution records.
LET’S PICTURE IT
A program can update its notebook and print a receipt describing the action.
SEE IT FOR YOURSELF
From an emitted Transfer event to a receipt logStep 1 / 4
A token implementation may update balances and emit its standard Transfer event. State and the emitted record are related but distinct.
A token implementation may update balances and emit its standard Transfer event. State and the emitted record are related but distinct.A non-anonymous Transfer event uses the full thirty-two-byte Keccak-256 signature digest as topic zero, not a four-byte function selector.In the common ERC-20 shape, from and to occupy topics one and two. The raw value is a thirty-two-byte data word. Other standards can index fields differently.An application can decode receipt logs under the correct ABI. A matching signature does not establish that an unknown emitter is an honest token.
Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.
Declare a typed event
An event signature specifies its name and parameter types. Indexed fields occupy topic positions under ABI rules, while remaining fields are encoded into the data region.
Emit during execution
The emit statement records a log in the execution context. A revert removes logs from the reverted portion along with its state changes, so not every attempted emit survives to the final receipt.
A log is not persistent variable storage
Contracts do not ordinarily read arbitrary historical logs as though they were a mapping. Apps can index logs, while later contract logic often needs explicit stored state.
Match the layout
A standard ERC-20 Transfer decoder expects one particular indexed/non-indexed arrangement. Other events, including similar signatures with different indexed fields, need their actual ABI.
Read the example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract LearningExample {
event Counted(address indexed caller, uint256 value);
uint256 public count;
function increment() external {
count += 1;
emit Counted(msg.sender, count);
}
}
The event reports a state update; the persistent count remains a separate variable.
QUICK CHECK · NO PRESSURE
Can a log emitted inside a reverted call remain as a successful surviving log of that reverted portion?
Reversion discards that call’s logs as well as its reverted state changes.