Smart Contract Language Solidity Tutorial Series 10 - Fully Understanding Function Modifiers

This is the 10th article in the Solidity tutorial series, which will give you a complete understanding of Solidity's function modifiers.
For a complete list of articles in the Solidity series, see Category - Solidity .

write in front

Solidity is the Ethereum smart contract programming language. Before reading this article, you should have some understanding of Ethereum and smart contracts.
If you don't know it yet, I suggest you first look at what Ethereum is.

Welcome to subscribe to the blockchain technology column to read more comprehensive analysis articles.

Function Modifiers

Function modifiers (Modifiers) can be used to change the behavior of a function. For example, it is used to check some kind of precondition before the function is executed.

If you are familiar with Python, you will find that the function modifier is very similar to the Python decorator.

A modifier is an inheritable contract property that can also be overridden by the inherited contract. Let's look at a sample code:

pragma solidity ^0.4.11;

contract owned {
    function owned() public { owner = msg.sender; }
    address owner;

    // 定义了一个函数修改器,可被继承
    //  修饰时,函数体被插入到 “_;” 处
    // 不符合条件时,将抛出异常
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
}

contract mortal is owned {
    //  使用继承的`onlyOwner` 
    function close() public onlyOwner {
        selfdestruct(owner);
    }
}

contract priced {
    // 函数修改器可接收参数
    modifier costs(uint price) {
        if (msg.value >= price) {
            _;
        }
    }
}

contract Register is priced, owned {
    mapping (address => bool) registeredAddresses;
    uint price;

    function Register(uint initialPrice) public { price = initialPrice; }

    // 需要提供payable 以接受以太
    function register() public payable costs(price) {
        registeredAddresses[msg.sender] = true;
    }

    function changePrice(uint _price) public onlyOwner {
        price = _price;
    }
}

The above onlyOwner is a function modifier defined. When a function is modified with this modifier area, the function must meet the conditions of onlyOwner to run. The condition here is: the contract must be created before the function can be called, otherwise an exception will be thrown .
We used this function modifier in a token article that implements advanced functions such as management, additional issuance, exchange, and freezing .

multiple modifiers

If there are multiple modifiers for the same function, separate them with spaces, and the modifiers will be checked for execution in sequence.

An explicit return statement inside a modifier or function simply exits the current modifier or function. The returned variable will be assigned, but the execution flow will continue after the "_" defined after the previous modifier, such as:

contract Mutex {
    bool locked;
    modifier noReentrancy() {
        require(!locked);
        locked = true;
        _;
        locked = false;
    }

    // 防止递归调用
    // return 7 之后,locked = false 依然会执行
    function f() public noReentrancy returns (uint) {
        require(msg.sender.call());
        return 7;
    }
}

The argument to the modifier can be any expression. In this context, all symbols introduced by the function are visible in the modifier. But symbols introduced in the modifier are not visible in the function, because they have the potential to be overridden.

Deep understanding of the order in which modifiers are executed

Let's look at a more complex example to understand modifiers in depth:


pragma solidity ^0.4.11;


contract modifysample {

    uint a = 10;

    modifier mf1 (uint b) {
        uint c = b;
        _;
        c = a;
        a = 11;
    }

     modifier mf2 () {
        uint c = a;
        _;
    }

    modifier mf3() {
        a = 12;
        return ;
        _;
        a = 13;
    }

    function test1() mf1(a) mf2 mf3 public   {
        a = 1;
    }

     function test2() public constant returns (uint)   {
        return a;  
    }  
}

After the smart contract above runs test1(), what is the value of the state variable a, is it 1, 11, 12, or 13?
The answer is 11, you can run test2 to get the next a value.

Let's analyze test1, which is expanded like this:

uint c = b;
        uint c = a;
            a = 12;
            return ;
            _;
            a = 13;
c = a;
a = 11;

At this time, it is clear at a glance, the last a is 11, pay attention to whether the 5th and 6th lines are executed.

references

Official Documentation - Function Modifiers

If you want to get to know me and establish contact with me, welcome to join the knowledge planet to explain the blockchain in simple terms. I will answer technical questions for everyone on the planet. As a star friend benefit, star friend can join the blockchain technology group created by me. It has gathered more than 100 blockchain technology enthusiasts.

Explain the blockchain in simple terms - learn blockchain systematically and create the best blockchain technology blog.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325376503&siteId=291194637