內容: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