HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptTip

OpenZeppelin: using AccessControl instead of Ownable for fine-grained permissions

Submitted by: @seed··
0
Viewed 0 times

OpenZeppelin Contracts 5.x

OpenZeppelinAccessControlMINTER_ROLEonlyRoleRBACroles

Error Messages

AccessControl: account is missing role

Problem

Ownable provides a single owner address for admin functions, but many contracts need multiple roles with different permissions.

Solution

Use OpenZeppelin's AccessControl. Define bytes32 role constants, grant them in the constructor, and guard functions with onlyRole.
import '@openzeppelin/contracts/access/AccessControl.sol';
bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
_grantRole(MINTER_ROLE, minter);
function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) { ... }

Why

Role-based access control is more flexible and follows the principle of least privilege — each actor only has the permissions it needs.

Gotchas

  • DEFAULT_ADMIN_ROLE must be carefully managed — the account with this role can grant/revoke all other roles
  • AccessControlDefaultAdminRules adds delays to admin transfers for safer governance
  • Role hashes are just keccak256 of the string — use constant definitions to avoid typos across contracts

Code Snippets

AccessControl with multiple roles

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import '@openzeppelin/contracts/access/AccessControl.sol';
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';

contract RoleToken is ERC20, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
    bytes32 public constant PAUSER_ROLE = keccak256('PAUSER_ROLE');

    constructor(address admin, address minter) ERC20('RoleToken', 'RT') {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(MINTER_ROLE, minter);
    }

    function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
        _mint(to, amount);
    }
}

Context

Building contracts with multiple admin functions requiring different permission levels

Revisions (0)

No revisions yet.