函數修飾符

2022-05-16 10:45 更新

修飾符可用于以聲明方式更改函數的行為。例如,您可以使用修飾符在執(zhí)行函數之前自動檢查條件。

修飾符是合約的可繼承屬性,可以被派生合約覆蓋,但前提是它們被標記為virtual。有關詳細信息,請參閱 修改器覆蓋。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.1 <0.9.0;

contract owned {
    constructor() { owner = payable(msg.sender); }
    address payable owner;

    // This contract only defines a modifier but does not use
    // it: it will be used in derived contracts.
    // The function body is inserted where the special symbol
    // `_;` in the definition of a modifier appears.
    // This means that if the owner calls this function, the
    // function is executed and otherwise, an exception is
    // thrown.
    modifier onlyOwner {
        require(
            msg.sender == owner,
            "Only owner can call this function."
        );
        _;
    }
}

contract destructible is owned {
    // This contract inherits the `onlyOwner` modifier from
    // `owned` and applies it to the `destroy` function, which
    // causes that calls to `destroy` only have an effect if
    // they are made by the stored owner.
    function destroy() public onlyOwner {
        selfdestruct(owner);
    }
}

contract priced {
    // Modifiers can receive arguments:
    modifier costs(uint price) {
        if (msg.value >= price) {
            _;
        }
    }
}

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

    constructor(uint initialPrice) { price = initialPrice; }

    // It is important to also provide the
    // `payable` keyword here, otherwise the function will
    // automatically reject all Ether sent to it.
    function register() public payable costs(price) {
        registeredAddresses[msg.sender] = true;
    }

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

contract Mutex {
    bool locked;
    modifier noReentrancy() {
        require(
            !locked,
            "Reentrant call."
        );
        locked = true;
        _;
        locked = false;
    }

    /// This function is protected by a mutex, which means that
    /// reentrant calls from within `msg.sender.call` cannot call `f` again.
    /// The `return 7` statement assigns 7 to the return value but still
    /// executes the statement `locked = false` in the modifier.
    function f() public noReentrancy returns (uint) {
        (bool success,) = msg.sender.call("");
        require(success);
        return 7;
    }
}

如果你想訪問一個m在 contract 中定義的修飾符C,你可以使用C.m它來引用它而無需虛擬查找。只能使用當前合約或其基礎合約中定義的修飾符。修飾符也可以在庫中定義,但它們的使用僅限于同一庫的函數。

通過在以空格分隔的列表中指定多個修飾符來將多個修飾符應用于函數,并按顯示的順序進行評估。

修飾符不能隱式訪問或更改它們修改的函數的參數和返回值。它們的值只能在調用時顯式傳遞給它們。

從修飾符或函數體顯式返回僅保留當前修飾符或函數體。_在前面的修飾符之后分配返回變量并且控制流繼續(xù)。

警告

在早期版本的 Solidity 中,return具有修飾符的函數中的語句表現(xiàn)不同。

從修飾符 with 顯式返回return;不會影響函數返回的值。然而,修飾符可以選擇根本不執(zhí)行函數體,在這種情況下,返回變量被設置為它們的默認值,就像函數有一個空的函數體一樣。

該_符號可以多次出現(xiàn)在修飾符中。每次出現(xiàn)都替換為函數體。

修飾符參數允許使用任意表達式,在這種情況下,從函數中可見的所有符號在修飾符中都是可見的。修飾符中引入的符號在函數中不可見(因為它們可能會因覆蓋而改變)。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號