💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 函数修改器(Function Modifiers) `修改器(Modifiers)`可以用来轻易的改变一个函数的行为。比如用于在函数执行前检查某种前置条件。修改器是一种合约属性,可被继承,同时还可被派生的合约`重写(override)`。下面我们来看一段示例代码: ``` pragma solidity ^0.4.0; contract owned { function owned() { owner = msg.sender; } address 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 { if (msg.sender != owner) throw; _; } } contract mortal is owned { // This contract inherits the "onlyOwner"-modifier from // "owned" and applies it to the "close"-function, which // causes that calls to "close" only have an effect if // they are made by the stored owner. function close() onlyOwner { selfdestruct(owner); } } contract priced { // Modifiers can receive arguments: modifier costs(uint price) { if (msg.value >= price) { _; } } } contract Register is priced, owned { mapping (address => bool) registeredAddresses; uint price; function Register(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() payable costs(price) { registeredAddresses[msg.sender] = true; } function changePrice(uint _price) onlyOwner { price = _price; } } ``` 修改器可以被继承,使用将`modifier`置于参数后,返回值前即可。 特殊`_`表示使用修改符的函数体的替换位置。 从合约`Register`可以看出全约可以多继承,通过`,`号分隔两个被继承的对象。 修改器也是可以接收参数的,如`priced`的`costs`。 使用修改器实现的一个防重复进入的例子。 ``` pragma solidity ^0.4.0; contract Mutex { bool locked; modifier noReentrancy() { if (locked) throw; 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() noReentrancy returns (uint) { if (!msg.sender.call()) throw; return 7; } } ``` 例子中,由于`call()`方法有可能会调回当前方法,修改器实现了防重入的检查。 如果同一个函数有多个修改器,他们之间以空格隔开,修饰器会依次检查执行。 > 需要注意的是,在Solidity的早期版本中,有修改器的函数,它的`return`语句的行为有些不同。 在修改器中和函数体内的显式的`return`语句,仅仅跳出当前的修改器和函数体。返回的变量会被赋值,但整个执行逻辑会在前一个修改器后面定义的"_"后继续执行。 修改器的参数可以是任意表达式。在对应的上下文中,所有的函数中引入的符号,在修改器中均可见。但修改器中引入的符号在函数中不可见,因为它们有可能被重写。