Function Modfiers

Published by Mario Oettler on

Another tool for dealing with unwanted behavior are function modifiers. Function modifiers change the behavior of a function. They are reusable and help to keep the code clean and readable. Function modifiers are used mostly to check a condition prior to executing the function.

Modifiers are declared in the contract using the keyword modifier. They are added to a function by naming them in the function declaration.

In the following example, we want to check if a passed number is below 100. Instead of checking this inside the function with a require statement, we put this check into a modifier.

pragma solidity 0.8.20;

contract modifierTest{
    
    uint256 threshold = 100;
    uint256 public number;
    
    modifier max100(uint256 number){
        require(number < threshold, "Number too big");
        _;
    }
    
    
    function setNumber(uint256 _number) public max100(_number){
        number = _number;
    }
}

The _; in line 10 means that if the modifier reaches this point, the function code is executed. After the function came to its end, the control flow jumps back to the modifier. The _; can occur multiple times in a modifier. The figure below shows the flow.

Modifier_Flow.jpg
pragma solidity 0.8.20;

contract modifierTest{
    
    uint256 public number;
    address public owner;
    
    constructor(){
        owner = msg.sender;
    }
    
    modifier onlyOwner(address _user){
        bool locked;
        require(msg.sender == owner, "Only the contract owner is allowed to call this function");
        require(!locked);
        locked = true;
        _;
        locked = false;
    }
    
    function setNumber(uint256 _number) public onlyOwner(msg.sender){
        number = _number;
    }
}

With this modifier, it is possible to implement a mutex to avoid reentrancy.

You can use multiple modifiers in a function by separating them with a space. The modifiers are executed in the order they were declared.

Modifiers are not limited to performing checks. It is also possible to send Ether and store state variables. But they cannot change function variables or function arguments.

Categories: