ERC-5982 Role-based access control standard (Role-based Access Control)

Review · Other · created 2022-11-15

Defines a common interface for querying, granting, creating, and deleting smart contract permissions by role. A role is represented as a bytes32 value, and its power is defined as the ability to call specific functions.

Why it is needed

Smart contracts have privileged functions, such as minting tokens or changing settings, that should not be callable by just anyone. The simplest way to protect these is ownership-based access control, which concentrates all permissions in a single owner account. Role-based access control, by contrast, assigns one or more roles to multiple users and grants access to privileged functions based on role. Following the principle of least privilege, necessary permissions can be split among multiple people, making this approach safer and more flexible than ownership-based control. However, when each contract implements role management differently, it becomes hard for wallets or tools to read the permission structure in a consistent way. This standard defines a single common interface for reading, granting, creating, and removing roles, and for expressing role metadata.

What to implement

In depth

Representing roles and the creation rule

A role is represented as a single bytes32 value. It is RECOMMENDED that the value be computed as the keccak256 hash of the role name, in the form bytes32 role = keccak256("<role_name>"). For example, a minter role is created as bytes32 role = keccak256("MINTER"). Because the role value is computed directly from a human-readable role name, anyone who knows the name can derive the same role value.

The required IERC_ACL_CORE interface

Contracts following the standard MUST implement IERC_ACL_CORE. This interface consists of three functions. hasRole(bytes32 role, address account) checks whether an account holds a role, grantRole(bytes32 role, address account) grants a role, and revokeRole(bytes32 role, address account) revokes a role. The function names and parameters were chosen to be backward compatible with the OpenZeppelin implementation. Also, a separate renounceRole function for self-renouncing a role was not adopted; it was folded into revokeRole to keep the interface simple.

Recommended extension IERC_ACL_GENERAL

IERC_ACL_GENERAL is a RECOMMENDED optional extension. It provides extended versions of grantRole, revokeRole, and hasRole that also pass arbitrary data _data, along with createRole and destroyRole for creating and removing roles, and setRolePower for setting a role's method permissions. createRole takes the role's admin role (adminOfRole), name, description (desc), and URI together. View functions such as canGrantRole, canRevokeRole, and canExecute let you check in advance which roles can grant roles, revoke roles, or execute methods. State changes are recorded via the RoleGranted, RoleRevoked, RoleCreated, RoleDestroyed, and RolePowerSet events. The _data parameter of these functions follows ERC-5750, allowing for future extensions.

A role's power is its ability to call methods

This standard defines a role's power as the ability to call a specific method identified by a bytes4 method selector. A role is no longer just an abstract title but is made concrete by which functions it can call. Calling setRolePower(bytes32 role, bytes4 methods, bytes calldata _data) to set a role's method permission emits a RolePowerSet event, and canExecute(bytes32 executor, bytes4 methods, bytes32 calldata payload, bytes calldata _data) lets you check in advance whether a given role can execute a given method.

Role metadata: IERC_ACL_METADATA

IERC_ACL_METADATA is an optional (MAY) extension. roleName(bytes32) returns a role's name, roleDescription(bytes32) returns its description, and roleURI(bytes32) returns a URI associated with the role. Since a role itself is a bytes32 value and hard for humans to read, implementing this interface lets wallets and tools display the role's meaning in a human-readable form. createRole in IERC_ACL_GENERAL also takes a name, desc, and uri when a role is created, and records them in the RoleCreated event.

ERC-165 support and proposal status

Compliant contracts SHOULD implement the ERC-165 identifier. This proposal requires ERC-165 and ERC-5750. Meanwhile, the original's Backwards Compatibility and Security Considerations sections are both still marked as needing discussion and have not yet been filled in. This proposal is currently in Review status, is not a finalized standard, and its content may still change.

Original ERC · ← ERCs