BC7: Writing smart contracts in Solidity

Lesson 3 of 5 · reading 15–25 minutes; practice and project time is on the module page

Who may do what: modifiers, errors and events

🎯You'll be able to

Restrict functions to the right callers, refuse bad input with clear errors, and record actions with events.

🏠The everyday picture

A bank counter with a sign saying "Account holders only", a clerk who explains exactly why a form is refused, and a ledger slip for every transaction.

📘What it really is

📝A worked example

Input: only the admin may add members, and the app must explain refusals.

Steps:

  1. modifier onlyAdmin() { if (msg.sender != admin) revert NotAdmin(); _; }.
  2. function addMember(address member) external onlyAdmin { ... emit MemberAdded(member); }.
  3. The app catches the error, decodes NotAdmin and shows "Only the group's admin can do that."

Expected output: the right callers, clear refusals and a searchable record.

🌍Where it's used

📝Case scenario

A contract checked tx.origin == owner. An attacker sent the owner a link to a "free airdrop" contract; when the owner called it, the attacker's contract called the victim contract, and the check passed because the owner had started the transaction. Switching to msg.sender stopped it.

🖱️Try it

Find the tx.origin check in the starter's addMember and explain, in two sentences, how the kit's Phisher contract uses it. Success: the admin calls Phisher, and Phisher calls addMember while tx.origin is still the admin.

⚠️Common mistakes

🛠️For your project

Project 1's test 4 uses the Phisher contract to check that only the admin can add members or pause.

✅Quick check

Why use msg.sender instead of tx.origin for authorisation?

Show the answer

tx.origin stays the original caller even when a malicious contract is in between.

What do custom errors give an app?

Show the answer

A named reason it can decode into plain words.

← PreviousSolidity basics: types, storage and functions
ProLearners Assist