# 函數修改器(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`語句,僅僅跳出當前的修改器和函數體。返回的變量會被賦值,但整個執行邏輯會在前一個修改器后面定義的"_"后繼續執行。
修改器的參數可以是任意表達式。在對應的上下文中,所有的函數中引入的符號,在修改器中均可見。但修改器中引入的符號在函數中不可見,因為它們有可能被重寫。
- Solidity語言
- 入門說明
- Solidity智能合約文件結構
- 智能合約源文件的基本要素概覽
- 值類型
- 類型
- 布爾
- 整型
- 地址
- 字節數組
- 小數
- 字符串
- 十六進制字面量
- 枚舉
- 函數
- 引用類型
- 引用類型
- 數據位置
- 數組
- 數據結構
- 雜項
- 映射
- 左值運算符
- 類型間的轉換
- 類型推斷
- 單位
- 貨幣單位
- 時間單位
- 語言內置特性
- 特殊變量及函數
- 數學和加密函數
- 地址相關
- 進階
- 入參和出參
- 控制結構
- 函數調用
- 創建合約實例
- 表達式的執行順序
- 賦值
- 作用范圍和聲明
- 異常
- 內聯匯編
- 合約詳解
- 合約
- 可見性或權限控制
- 訪問函數
- 函數修改器
- 常狀態變量
- 回退函數
- 事件
- 繼承
- 接口
- 其它
- 庫
- 狀態變量的存儲模型
- 內存變量的存局
- 調用數據的布局