ICE 3 – Events & Logs (Remix)

Goal: add events to a contract, emit on set(), then find and interpret logs in Remix (including indexed topics).

1) Why events?

2) Contract with an event

Create SimpleStorageEvents.sol and paste:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorageEvents {
    uint256 private storedData;

    // Event with three indexed topics for fast filtering
    event ValueChanged(
        uint256 indexed oldValue,
        uint256 indexed newValue,
        address indexed setter
    );

    function set(uint256 x) public {
        uint256 oldVal = storedData;
        storedData = x;
        emit ValueChanged(oldVal, x, msg.sender);
    }

    function get() public view returns (uint256) {
        return storedData;
    }
}

3) Compile & Deploy

  1. Open remix.ethereum.org.
  2. Solidity Compiler → select 0.8.xCompile SimpleStorageEvents.sol.
  3. Deploy & Run → Environment:
    • Remix VM (Prague) for quick demo, or
    • Injected Provider – MetaMask to log on Ganache (from ICE 2).
  4. Select SimpleStorageEventsDeploy → confirm (if MetaMask).

4) Emit and read logs

  1. In Deployed Contracts, expand the instance.
  2. Call set(42) → confirm.
  3. Open the terminal at the bottom; click the transaction entry.
  4. In the tx details, find the logs/events section → you’ll see ValueChanged with topics and data.
    • topics[0]: event signature hash
    • topics[1..3]: indexed params → oldValue, newValue, setter
    • data: non-indexed parameters (none here)
  5. Call get() → returns 42.

On Ganache, you can also inspect the receipt in Ganache’s Transactions tab for the same event.

5) Frontend note (ethers.js)

// Listen for events (ethers v6)
import { BrowserProvider } from "ethers";
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const c = new ethers.Contract(addr, abi, signer);
c.on("ValueChanged", (oldV, newV, who, ev) => {
  console.log("ValueChanged", oldV.toString(), newV.toString(), who);
});

Events are the preferred way to notify UIs of changes; avoid scanning storage in loops.

Troubleshooting

  • No logs? Make sure you called set(), not just get().
  • Gas estimation failed: On Ganache, ensure the selected MetaMask account has test ETH (see ICE 2).
  • Wrong network: If using Injected Provider, MetaMask must be on Ganache (localhost) or a testnet.

Submission (what to turn in)

Next: ICE 4 – Frontend (ethers.js): build a tiny web page that connects to MetaMask and calls set/get, listening for events.