James Bachini

Implementing RBAC Patterns in Solidity

Access Control

We can implement role based access control or RBAC patterns in Solidity using OpenZeppelin’s AccessControl.sol library. This allows developers to manage different roles and assign permissions dynamically. Here’s a step by step guide based on the information provided.

Understanding Roles in Access Control

The essence of RBAC in Solidity involves defining roles, where each role has specific permissions. Roles are defined using bytes32 identifiers, typically hashed strings, and are used to check permissions using the onlyRole modifier.

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

This defines two roles, MINTER_ROLE and BURNER_ROLE, which allow minting and burning tokens, respectively.

Setting Up an AccessControl Contract

o implement RBAC, import the AccessControl contract from OpenZeppelin. You can then use it to define, assign, and check roles.

Here’s an example contract that implements an ERC20 token with minting and burning functionality, controlled by roles:

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

import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract AccessControlERC20Mint is ERC20, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

    constructor(address minter, address burner) ERC20("MyToken", "TKN") {
        _grantRole(MINTER_ROLE, minter);
        _grantRole(BURNER_ROLE, burner);
    }

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

    function burn(address from, uint256 amount) public onlyRole(BURNER_ROLE) {
        _burn(from, amount);
    }
}

Here we use the _grantRole function to grant two addresses minter and burner privileges in the constructor function which runs once when the contract is first deployed.

The mint and burn functions then use the onlyRole modifier to ensure any user calling them has the privileges.

Additional Access Control Functionality

Default Admin Role

Each role has an admin role that manages permissions related to granting and revoking the role. By default, DEFAULT_ADMIN_ROLE is the admin for all roles, but you can change this using _setRoleAdmin if you need to decentralize the management of roles.

_setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);
Querying Accounts with Roles

To check which accounts have been assigned a particular role, you can use getRoleMemberCount and getRoleMember

uint256 minterCount = getRoleMemberCount(MINTER_ROLE);
address minter = getRoleMember(MINTER_ROLE, 0); // Retrieves the first minter

By leveraging OpenZeppelin’s AccessControl, devs can implement a flexible and secure RBAC system in Solidity, ensuring that different accounts have the appropriate permissions to interact with your smart contracts.


Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.