內容:modifier的定義、modifier對函式引數的操作、modifier執行的順序
modifier的定義
官方文件:modifier可以改變函式的行為。可以被繼承和重寫。
其實modifier被用於最多的是行為檢查,這樣可以使得減少檢查程式碼的複用以及讓程式碼看起來更簡介易懂。比如,檢查呼叫者是否有許可權執行這個函式,傳入的引數是否有錯誤等等。但是modifier不僅僅於此。通過一下一個例子來熟悉瞭解一下modifier的用法:
// 建立了一個NoteBook的合約,只有NoteBook的擁有者才可以修改其內容record
contract NoteBook{
string public record; // NoteBook的內容
address owner; // NoteBook的擁有者
constructor() {
owner = msg.sender;
}
// 修改record的內容
function changeRecord(string memory _record) public isOwner {
record = _record;
}
// 函式修改器:判斷是否是NoteBook的
modifier isOwner{
require(msg.sender == owner, "You are not the owner of this NoteBook");
_;
}
}
上述例子中,我們通過關鍵字 modifier
後面接函式修改器名 NoteBook
來定義一個modifier。在上述定義的modifier中如果呼叫者不是擁有者則會停止執行接下來的程式碼,並在控制檯輸出自定義的原因。如果是的話則執行到 _
處,_
代表使用該modifier的函式體,這裡即為changeRecord
函式的函式體。在執行changeRecord
函式前先會使用isOwner進行檢查,沒有問題後才會執行。
modifier對函式引數的操作
執行函式時有時候也會對函式的引數有所要求,為了讓函式內的程式碼更簡潔我們便可以寫在modifier中。那如何對函式引數進行檢查呢?這個和函式的操作一樣,呼叫時傳參便可。看如下例子:
// 這個合約可以執行運算
contract Operation{
// 除法運算
function division(uint256 opt1, uint256 opt2) public checkZero(opt2) pure returns(uint256){
return opt1 / opt2;
}
// 檢查除數是否為0
modifier checkZero(uint256 divisor) {
require (divisor != 0, "divisor can't be 0");
_;
}
}
在以上程式碼中我們需要做的是檢查除法運算中的除數是否為0,若是0則中止執行,並給予提示。程式碼簡單就不囉嗦了。
當然modifier還可以對storage中的變數進行檢查,
modifier的執行順序
一個函式可能需要做多個檢查,那麼我們可以寫多個modifier,呼叫時只需將每個modifier以空格隔開。而檢查順序也就是modifier們的排列順序。
但還有一種可能會迷惑大家的寫法:
contract modifierOder {
address owner;
uint256 a;
constructor() {
owner = msg.sender;
}
function test(uint num) public checkPara(num) returns(uint256) {
a = 10;
return a;
}
// 修改a
modifier checkPara(uint number) {
a = 1;
_;
a = 100;
}
}
如以上程式碼所示:在 _
後又有一句程式碼a = 100
。函式執行完return
後,後面的程式碼則不再執行,但是在modifier中,執行完函式體 _
還會接著執行 a = 100
這條語句。所以儘管函式返回的a
的值為10,但是最後a
的值變成了100。
以上所有程式碼都是給予solidity 0.7.x的編譯器
以上就是所有內容的,有不妥之處,敬請大家指正。
參考連結:
https://me.tryblockchain.org/blockchain-solidity-functionModifier.html
https://learnblockchain.cn/docs/solidity/contracts.html#modifiers