Solidity Fundamentals

Lesson 4 of 7

Modifiers and Access Control

A modifier wraps reusable logic, most commonly an access-control check, around a function, avoiding copy-pasting the same require statement into every function that needs it.

contract Vault {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not the owner");
        _;   // this is where the wrapped function's body runs
    }

    function withdraw(uint256 amount) public onlyOwner {
        // only the owner can ever reach this point
    }

    function setOwner(address newOwner) public onlyOwner {
        owner = newOwner;
    }
}

The _; inside a modifier marks exactly where the decorated function's own body gets spliced in, everything before _; runs first (here, the ownership check), and if require fails, the function body after it never executes at all, the whole transaction reverts.

require, revert, and assert

function transfer(address to, uint256 amount) public {
    require(amount > 0, "Amount must be positive");   // validate input
    require(balance[msg.sender] >= amount, "Insufficient balance");
    balance[msg.sender] -= amount;
    balance[to] += amount;
}

require checks a condition and reverts the entire transaction (undoing every state change made so far in it) with an error message if it fails, this all-or-nothing behavior is fundamental, a smart contract transaction can never be left half-finished.

📝 Modifiers and Access Control Quiz

Passing score: 70%
  1. 1.What does _; represent inside a modifier?

  2. 2.If a require() check fails partway through a function, all state changes made earlier in that same transaction are undone.

  3. 3.A reusable block of logic, commonly an access check, wrapped around a function is called a ____.