Modifiers – Go With The Flow

Modifiers – Go With The Flow

What is a modifier

Modifiers are a neat feature in Solidity that allows us to change the flow of our code execution. The modifiers (as the name suggest) can modify the code of a function.

Look at the following contract:

contract A{
    
    uint public number;

    modifier zeroNum(){
        number = 0;
        _;
    }

    function plusNumber(uint _input){
        number = number + input;
    }  
}
In the code above, the modifier zeroNum is executed right before the rest of the function. It reset the number value back to zero. If it wasn’t for that modifier, the numbers would have just continue to add up.
Modifiers are mostly used as a gateways in our smart contracts:
contract B{

    address public owner = msg.sender;

    modifier onlyOwner(){
        assert(msg.sender == owner);
        _;
    }

    function register()onlyOwner(){
    //Do stuff
    }
}

In this example, only the owner of the smart contract can execute the rest of the function code.

Here’s another example in which the modifier that prevents anyone below the age of eight-teen to register:

contract C{

    address public owner = msg.sender;
    string public name;
    uint public age;

    modifier onlyOwner(){
        assert(msg.sender == owner);
        _;
    }

    modifier notMinors(uint _age){
        require(_age>18);
        _;
    }

    function register(string _name, uint _age)onlyOwner() notMiner(_age){
        name = _name;
        age = _age;
    }
}

The underscore.

Each modifier contains an underscore, this is where the rest of the code is inserted. The underscore can also be nested inside the modifier.
contract D{
    
    uint public input;
    uint public number;

    modifier onlyOwner(uint _input){
        assert(msg.sender == owner);
        input = _input + 1;
        _;
        input = _input + 2;
    }

    function doStuff(uint _input) onlyOwner(_input){
        number = input +1; //At the time of the code execution
    }
}

The difference between require and assert

Two powerful commands are assert and require. Both aren’t necessarily related to modifiers; in fact you can use these two in any function. However, they’re beneficial when trying to follow the execution flow of the code. Both will perform some logical test and will either allow the code to continue or throw the code. Throwing is the process by which the states of the EVM is reverted to the ones before the code execution. Also, currently throwing takes all of the gas associated with that transaction. In the future, the require command will refund the users of their unused gas and might even return some value.

Multiple modifiers

We can use more than one modifier in function. Modifiers will be loaded and nested according to their order.
function doStuff() modifierOne() modifierTwo() modifiersThree(){
    //TO DO
}

Predefined modifiers in Solidity:

 
public       - called by everyone
external     - Can only be called by external function (or by "this.functionName")
private      - can only be called by functions within the contract or from its derivatives 
internal     - Can only be called internally 

payable      - can accept Ethers
constant     - don't send transactions function is executed locally

Side note – The difference between require and assert

Two powerful commands are: assert and require. Both aren’t necessarily related to modifiers; in fact you can use these two in any function. However, they’re beneficial when trying to follow the execution flow of the code. Both will perform some logical test and will either allow the code to continue or throw the code. Throwing is the process by which the states of the EVM is reverted to the ones before the code execution. Also, currently throwing takes all of the gas associated with that transaction. In the future, the require command will refund the users of their unused gas and might even return some values.
For now there's no change (both throws). In the future:
require - revert but won't take all gas. It will refund the user and return a value
assert - like the old throw - revert changes and consume all gas

Leave a Reply

Your email address will not be published. Required fields are marked *