- Modifiers are declared with the modifier keyword as follows:
modifier modifierName {
// modifier definition
}
- The function body is inserted where the _ symbol appears in the definition of a modifier:
modifier onlyOwner {
require(msg.sender == owner);
_;
}
- Modifiers can accept parameters like functions do. The following example creates a generic modifier to verify the caller address:
contract Test {
address owner;
constructor() public {
owner = msg.sender;
}
modifier onlyBy(address user) {
require(msg.sender == user);
_;
}
function donate() onlyBy(owner) public {
// do something
}
}
- Multiple modifiers can be specified in a function. They will be evaluated in the order given:
contract modifierContract {
address owner;
constructor() {
owner == msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier valueGreaterThan(uint value) {
require(msg.value > value);
_;
}
function sendEther() onlyOwner valueGreaterThan(1 ether) public {
// Function body
}
}
- Modifiers can be inherited from other contracts and can also be overridden:
contract Ownership {
address owner;
function Ownership() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
}
contract Donate is Ownership {
bool locked; modifier noReentrancy() { require(!locked); locked = true; _; locked = false; }
function claim() onlyOwner public {
require(msg.sender.call());
}
function donate(address _user) noReentrancy public {
require(_user.call());
}
}
It is recommended to use modifiers often to validate function execution, as they express what actions are occurring in a readable and declarative manner.