Modifier
modifier 可以用来改变函数的主体。如果使用了这个modifier,它会预先执行一个检查,只有当函数从某个地址被调用时才会通过。
pragma solidity ^0.4.0;
contract owned {
function owned() { owner = msg.sender; }
address owner;
modifier onlyOwner {
if (msg.sender != owner)
throw;
_;
}
}
contract mortal is owned {
function close() onlyOwner {
selfdestruct(owner);
}
}
contract Register is priced, owned {
mapping (address => bool) registeredAddresses;
uint price;
function Register(uint initialPrice) { price = initialPrice; }
function register() payable costs(price) {
registeredAddresses[msg.sender] = true;
}
function changePrice(uint _price) onlyOwner {
price = _price;
}
}
- modifier可以被继承,使用将
modifier
置于参数后,返回值前即可。 - 特殊
_
表示使用修改符的函数体的替换位置。 - modifier也是可以接收参数的,如
priced
的costs
。
使用modifier实现的一个防reentry攻击的例子。
pragma solidity ^0.4.0;
contract Mutex {
bool locked;
modifier noReentrancy() {
if (locked) throw;
locked = true;
_;
locked = false;
}
/// 这个方法被互斥锁保护,意味着 重入攻击者不能多次调用f方法
function f() noReentrancy returns (uint) {
if (!msg.sender.call()) throw;
return 7;
}
}
例子中,由于call()
方法有可能会调回当前方法,修改器实现了防重入的检查。
如果同一个函数有多个修改器,他们之间以空格隔开,修饰器会依次检查执行。
在修改器中和函数体内的显式的return
语句,仅仅跳出当前的修改器和函数体。返回的变量会被赋值,但整个执行逻辑会在前一个修改器后面定义的"_"后继续执行。
实例:
这种情况下,m2会被添加到a = 1;之前,所以返回m1的值:
这种情况m2被添加在m1之后,所以返回m2的值:
结合前两种情况,这种情况的返回值是11。
分析:
可以看做:m2的内容是m1的 _