Modifiers and Access Control
Reuse validation logic with modifiers.
Code
contract AccessControl {
address public owner;
mapping(address => bool) public admins;
uint256 public pausedAt;
modifier onlyOwner() {
require(msg.sender == owner, "Only owner");
_;
}
modifier onlyAdmin() {
require(admins[msg.sender], "Only admin");
_;
}
modifier whenNotPaused() {
require(pausedAt == 0, "Paused");
_;
}
// Reentrancy guard (prevents reentrancy attacks)
uint256 private _status;
modifier nonReentrant() {
require(_status != 2, "Reentrant");
_status = 2;
_;
_status = 1;
}
constructor() {
owner = msg.sender;
_status = 1;
}
function addAdmin(address a) external onlyOwner {
admins[a] = true;
}
function criticalOp() external onlyAdmin whenNotPaused nonReentrant {
// ... sensitive logic
}
function pause() external onlyOwner {
pausedAt = block.timestamp;
}
}Explanation
Modifiers wrap functions with reusable pre/post checks — _; marks where the function body runs. Common patterns: onlyOwner (access control), whenNotPaused (circuit breaker), nonReentrant (reentrancy guard — prevents callbacks during execution). Stack modifiers to combine. Always put nonReentrant on functions that call external contracts to prevent reentrancy attacks.
More Solidity Snippets
Contract Basics
Define a basic smart contract with state and functions.
Functions and Visibility
Function visibility, payable, and return values.
Events and Logs
Emit events for off-chain listeners.
Mappings, Structs & Nested Storage
Group related data with structs and look it up by key with mappings.
Inheritance, Abstract & Interfaces
Reuse logic via inheritance; define contracts with abstract and interface.
Payable, receive & fallback (ETH flows)
Receive ETH via payable functions and the receive/fallback hooks.