access_control

Access control, that is, "who is allowed to do this thing", is incredibly important in the world of decentralized programs. The access control of your program may govern who can mint tokens, vote on proposals, freeze transfers, and many other things. It is therefore critical to understand how you implement it, lest someone else steals your whole system. We implement access control in a way that is both secure and flexible, which is called role-based access control (RBAC).

Role-based access control is a policy-neutral access control mechanism defined around roles and privileges. In essence, we will be defining multiple roles, each allowed to perform different sets of actions. An account may have, for example, 'moderator', 'minter' or 'admin' roles, which you will then check for. This check can be enforced through the only_role or check_role transition. Separately, you will be able to define rules for how accounts can be granted a role, have it revoked, and more.

Every role has an associated admin role, which grants permission to call the grant_role and revoke_role transitions. A role can be granted or revoked by using these if the calling account has the corresponding admin role. Multiple roles may have the same admin role to make management easier. A role’s admin can even be the same role itself, which would cause accounts with that role to be able to also grant and revoke it.

This mechanism can be used to create complex permissioning structures resembling organizational charts, but it also provides an easy way to manage simpler applications. The program includes a special role, called DEFAULT_ADMIN_ROLE (with value 0u8), which acts as the default admin role for all roles. An account with this role will be able to manage any other role, unless set_role_admin is used to select a new admin role.

Mappings, Structs and Records

All the mappings can be read publicly, either by the user or by the programs.

grants

Returns whether the account has the role. The key is the BHP256 hash of the grant struct instance.

struct grant {
    account: address,
    role: u8,
}

mapping grants: field => bool;

role_admins

Returns the admin role of the role. Role is represented by a u8 number.

mapping role_admins: u8 => u8;

initialized

Returns whether the mapping has been initialized. The only valid key is 0u8.

mapping initialized: u8 => bool;

Transitions

only_role

Check whether the caller has the role. If not, the transition will fail.

async transition only_role(public role: u8) -> Future;

check_role

Check whether the account has the role. If not, the transition will fail.

async transition check_role(public role: u8, public account: address) -> Future;

check_role_admin

Check whether the account account has the admin role of the role role.

async transition check_role_admin(public role: u8, public account: address) -> Future;

set_role_admin

Set admin_role as the admin role of the role role. The caller must have the DEFAULT_ADMIN_ROLE role.

async transition set_role_admin(public role: u8, public admin_role: u8) -> Future;

grant_role

Grant the role role to the account account.

async transition grant_role(public role: u8, public account: address) -> Future;

revoke_role

Revoke the role role from the account account.

async transition revoke_role(public role: u8, public account: address) -> Future;

renounce_role

Renounce the role role from the account account. The account must be the caller itself. That is, only the caller can renounce its own role.

async transition renounce_role(public role: u8, public account: address) -> Future;

Admin Transitions

The following transitions can only be called by the admin. The admin should be an administrator program, which is managed by the Spectre Governance.

initialize

Initializes the access control program. It will grant the DEFAULT_ADMIN_ROLE role to the caller. Actually, the caller address must be the same as the constant INITIAL_ADMIN written in the program before deployment.

async transition initialize() -> Future;

Last updated