Track 4 · Solidity foundations · lesson 10
Modifiers
9 min
Track 4 · Solidity foundations · lesson 10
9 min
You have now written the same owner check twice. A modifier is how you write it once.
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
function withdraw(uint256 amount) public onlyOwner { ... }
The _; is the important part. It marks where the guarded function's body gets
spliced in.
Code above _; runs before the function. Code below runs after. A modifier can
have both, and can even leave out _; entirely — in which case the function
never runs at all.
A modifier does nothing you could not do with a plain if at the top of the
function. What it buys you is that the guard is visible in the signature —
you can audit which functions are protected by reading the function list, rather
than reading every body.
That is a real benefit, and it comes with a matching risk.
Predict
Multiple modifiers run left to right:
function withdraw() public onlyOwner whenNotPaused nonReentrant { ... }
onlyOwner runs first, then whenNotPaused, then nonReentrant, then the
body. If a guard reverts, nothing after it runs.
Because _; marks the splice point, a modifier can wrap the function on both
sides:
modifier nonReentrant() {
require(!locked, "reentrant");
locked = true;
_;
locked = false;
}
This is the reentrancy guard, and it is the single most important modifier in Solidity. You will write it yourself in track 7 — immediately after using its absence to drain a vault of 100 ETH.
Check