🎓 A1Learner
🔍
0 of 50 lessons completed

Solidity Modifiers

A modifier is a reusable check that wraps a function and runs before the function body. The body runs only if the check passes.

onlyOwner guards a function

The constructor records the deployer as owner. The modifier compares every caller with that stored address.

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

contract Settings {
    address public owner;
    uint256 public fee;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "only the owner");
        _;
    }

    function setFee(uint256 newFee) public onlyOwner {
        fee = newFee;
    }
}

A gate modifier checks an open flag

Modifiers are general, not just for owners. This one lets the body run only while the club is open.

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

contract Club {
    bool public open;
    uint256 public visits;

    modifier whenOpen() {
        require(open, "the club is closed");
        _;
    }

    function setOpen(bool newOpen) public {
        open = newOpen;
    }

    function visit() public whenOpen {
        visits += 1;
    }
}

Two modifiers can guard one function

setFee carries both modifiers, so both checks must pass. The owner must open the club before the fee can change.

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

contract ClubSettings {
    address public owner;
    bool public open;
    uint256 public fee;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "only the owner");
        _;
    }

    modifier whenOpen() {
        require(open, "the club is closed");
        _;
    }

    function setOpen(bool newOpen) public onlyOwner {
        open = newOpen;
    }

    function setFee(uint256 newFee) public onlyOwner whenOpen {
        fee = newFee;
    }
}

Example

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

contract CommunityChest {
    address public owner;
    bool public open;
    uint256 public totalPaid;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "only the owner");
        _;
    }

    modifier whenOpen() {
        require(open, "the chest is closed");
        _;
    }

    function setOpen(bool newOpen) public onlyOwner {
        open = newOpen;
    }

    function deposit() public payable {}

    function payOut(address payable to, uint256 amount) public onlyOwner whenOpen {
        (bool ok, ) = to.call{value: amount}("");
        require(ok, "payment failed");
        totalPaid += amount;
    }
}

Key points

  • Modifier: a named block of checks written once and attached to any function.
  • Underscore: the _; line inside a modifier marks the place where the wrapped function's body runs.
  • Attach: write the modifier's name after the function header to apply it.
  • onlyOwner: a common modifier that lets a call through only when msg.sender matches the stored owner.
  • Owner: the owner is often the deploying account, meaning the account that put the contract on the network, recorded in the constructor.
  • Generality: a modifier can check anything, such as an open flag, not just the caller.

In this example, the CommunityChest contract records its deployer as owner in the constructor. The onlyOwner modifier guards setOpen and payOut, and the whenOpen modifier also guards payOut. The deposit function stays open to everyone, so anyone can add ether. A payout runs only when the caller is the owner and the chest is open, and totalPaid tracks how much has been paid.

Note

one function can carry several modifiers, and they run in the order written.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Remix IDE

Exercise

What does the _; line inside a modifier stand for?