我们可以将modifier理解为一个方法,对function的函数进行权限管理+代码复用。_;里面就是复用的代码,就是function函数里面的。打个比喻,就是我说我喜欢男孩子,function boy() public{},但是我modifier boy{require(boy=handsome); _;}。如果按照这个顺序,那我在人群中先定义我要找的是男孩子,后面再modifier;但是一般情况下,modifier会放在前面,所以先找帅哥,再执行_;也就是boy()。
例子1:
pragma solidity ^0.4.11; contract owned { function owned() public { owner = msg.sender; } address owner; // 这个合约只定义一个修饰器,但并未使用: 它将会在派生合约中用到。 // 修饰器所修饰的函数体会被插入到特殊符号 _; 的位置。 // 这意味着如果是 owner 调用这个函数,则函数会被执行,否则会抛出异常。 //modifier(修饰器),我们可以理解为代码复用,在智能合约中一般用于“权限判断”。比如一个合约中,不同用户的权限不同,onlyowner()本来为public权限,拥有者可以是发送者,但是modifier后,发送者必须是拥有者,就不能代转了 modifier onlyOwner { require(msg.sender == owner); _; //先运行require里面的函数,如果为true则继续运行下面的onlyOwner(),但是这里没有这个函数。。。这憨憨例子。。 } } contract mortal is owned { // 这个合约从 `owned` 继承了 `onlyOwner` 修饰符,并将其应用于 `close` 函数, // 只有在合约里保存的 owner 调用 `close` 函数,才会生效。 function close() public onlyOwner { selfdestruct(owner); } } contract priced { // 修改器可以接收参数: modifier costs(uint price) { if (msg.value >= price) { _; } } } contract Register is priced, owned { mapping (address => bool) registeredAddresses; uint price; function Register(uint initialPrice) public { price = initialPrice; } // 在这里也使用关键字 `payable` 非常重要,否则函数会自动拒绝所有发送给它的以太币。 function register() public payable costs(price) { registeredAddresses[msg.sender] = true; } function changePrice(uint _price) public onlyOwner { price = _price; } } contract Mutex { bool locked; modifier noReentrancy() { require(!locked); locked = true; _; locked = false; } // 这个函数受互斥量保护,这意味着 `msg.sender.call` 中的重入调用不能再次调用 `f`。 // `return 7` 语句指定返回值为 7,但修改器中的语句 `locked = false` 仍会执行。 function f() public noReentrancy returns (uint) { require(msg.sender.call()); return 7; } }
https://bbs.huaweicloud.com/blogs/223213
例子2:
pragma solidity ^0.4.22; contract Purchase { address public seller; modifier onlySeller() { // 修饰器,这时即将调用onlyseller(),但是先require require( msg.sender == seller, "Only seller can call this." ); _;//只运行满足require的 } function abort() public onlySeller { // Modifier usage // } }