Access Control
This crate provides ways to restrict who can access the functions of a contract or when they can do it.
- Ownable is a simple mechanism with a single "owner" role that can be assigned to a single account. This mechanism can be useful in simple scenarios, but fine grained access needs are likely to outgrow it.
- AccessControl provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts.
Interfaces
use openzeppelin_access::accesscontrol::interface::IAccessControl;
External interface of AccessControl.
0x23700be02858dbe2ac4dc9c9f66d0b6b0ed81ec7f970ca6844500a56ff61751
Functions
has_role(role, account)
get_role_admin(role)
grant_role(role, account)
revoke_role(role, account)
renounce_role(role, account)
Events
RoleAdminChanged(role, previous_admin_role, new_admin_role)
RoleGranted(role, account, sender)
RoleRevoked(role, account, sender)
Functions
has_role(role: felt252, account: ContractAddress) → bool
external
#Returns whether account
can act as role
.
get_role_admin(role: felt252) → felt252
external
#Returns the admin role that controls role
. See grant_role and revoke_role.
To change a role’s admin, use set_role_admin.
grant_role(role: felt252, account: ContractAddress)
external
#Grants role
to account
.
If account
had not been already granted role
, emits a RoleGranted event.
Requirements:
- the caller must have
role
's admin role.
revoke_role(role: felt252, account: ContractAddress)
external
#Revokes role
from account
.
If account
had been granted role
, emits a RoleRevoked event.
Requirements:
- the caller must have
role
's admin role.
renounce_role(role: felt252, account: ContractAddress)
external
#Revokes role
from the calling account.
Roles are often managed via grant_role and revoke_role. This function’s purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced).
If the calling account had been granted role
, emits a RoleRevoked event.
Requirements:
- the caller must be
account
.
Events
RoleAdminChanged(role: felt252, previous_admin_role: ContractAddress, new_admin_role: ContractAddress)
event
#Emitted when new_admin_role
is set as role
's admin role, replacing previous_admin_role
DEFAULT_ADMIN_ROLE
is the starting admin for all roles, despite RoleAdminChanged not being emitted signaling this.
RoleGranted(role: felt252, account: ContractAddress, sender: ContractAddress)
event
#Emitted when account
is granted role
.
sender
is the account that originated the contract call, an account with the admin role or the deployer address if _grant_role
is called from the constructor.
RoleRevoked(role: felt252, account: ContractAddress, sender: ContractAddress)
event
#Emitted when account
is revoked role
.
sender
is the account that originated the contract call:
- if using
revoke_role
, it is the admin role bearer. - if using
renounce_role
, it is the role bearer (i.e.account
).
use openzeppelin_access::accesscontrol::interface::IAccessControlWithDelay;
External interface for the extended AccessControlWithDelay
functionality.
Functions
Events
Functions
get_role_status(role: felt252, account: ContractAddress) → RoleStatus
external
#Returns the account’s status for the given role. The possible statuses are:
NotGranted
: the role has not been granted to the account.Delayed
: The role has been granted to the account but is not yet active due to a time delay.Effective
: the role has been granted to the account and is currently active.
grant_role_with_delay(role: felt252, account: ContractAddress, delay: u64)
external
#Attempts to grant role
to account
with the specified activation delay.
Requirements:
- The caller must have
role
's admin role. - delay must be greater than 0.
- the
role
must not be already effective foraccount
.
May emit a RoleGrantedWithDelay event.
Events
RoleGrantedWithDelay(role: felt252, account: ContractAddress, sender: ContractAddress, delay: u64)
event
#Emitted when account
is granted role
with a delay.
sender
is the account that originated the contract call, an account with the admin role or the deployer address if _grant_role_with_delay is called from the constructor.
Core
use openzeppelin_access::ownable::OwnableComponent;
Ownable
provides a basic access control mechanism where an account (an owner) can be granted exclusive access to specific functions.
This module includes the internal assert_only_owner
to restrict a function to be used only by the owner.
Embeddable Mixin Implementations
OwnableMixinImpl
OwnableTwoStepMixinImpl
Embeddable Implementations
OwnableImpl
OwnableTwoStepImpl
owner(self)
pending_owner(self)
accept_ownership(self)
transfer_ownership(self, new_owner)
renounce_ownership(self)
OwnableCamelOnlyImpl
OwnableTwoStepCamelOnlyImpl
Internal Implementations
InternalImpl
initializer(self, owner)
assert_only_owner(self)
_transfer_ownership(self, new_owner)
_propose_owner(self, new_owner)
Events
Embeddable functions
owner(self: @ContractState) → ContractAddress
external
#Returns the address of the current owner.
transfer_ownership(ref self: ContractState, new_owner: ContractAddress)
external
#Transfers ownership of the contract to a new account (new_owner
). Can only be called by the current owner.
Emits an OwnershipTransferred event.
renounce_ownership(ref self: ContractState)
external
#Leaves the contract without owner. It will not be possible to call assert_only_owner
functions anymore. Can only be called by the current owner.
Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.
Embeddable functions (two step transfer)
owner(self: @ContractState) → ContractAddress
external
#Returns the address of the current owner.
pending_owner(self: @ContractState) → ContractAddress
external
#Returns the address of the pending owner.
accept_ownership(ref self: ContractState)
external
#Transfers ownership of the contract to the pending owner. Can only be called by the pending owner. Resets pending owner to zero address.
Emits an OwnershipTransferred event.
transfer_ownership(ref self: ContractState, new_owner: ContractAddress)
external
#Starts the two step ownership transfer process, by setting the pending owner. Setting new_owner
to the zero address is allowed, this can be used to cancel an initiated ownership transfer.
Can only be called by the current owner.
Emits an OwnershipTransferStarted event.
renounce_ownership(ref self: ContractState)
external
#Leaves the contract without owner. It will not be possible to call assert_only_owner
functions anymore. Can only be called by the current owner.
Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.
transferOwnership(ref self: ContractState, newOwner: ContractAddress)
external
#See transfer_ownership.
renounceOwnership(ref self: ContractState)
external
#See renounce_ownership.
pendingOwner(self: @ContractState)
external
#See pending_owner.
acceptOwnership(self: @ContractState)
external
#See accept_ownership.
transferOwnership(self: @ContractState)
external
#See transfer_ownership.
renounceOwnership(self: @ContractState)
external
#See renounce_ownership.
Internal functions
initializer(ref self: ContractState, owner: ContractAddress)
internal
#Initializes the contract and sets owner
as the initial owner.
Requirements:
owner
cannot be the zero address.
Emits an OwnershipTransferred event.
assert_only_owner(self: @ContractState)
internal
#Panics if called by any account other than the owner.
_transfer_ownership(ref self: ContractState, new_owner: ContractAddress)
internal
#Transfers ownership of the contract to a new account (new_owner
). Internal function without access restriction.
Emits an OwnershipTransferred event.
_propose_owner(ref self: ContractState, new_owner: ContractAddress)
internal
#Sets a new pending owner in a two step transfer.
Internal function without access restriction.
Emits an OwnershipTransferStarted event.
Events
OwnershipTransferStarted(previous_owner: ContractAddress, new_owner: ContractAddress)
event
#Emitted when the pending owner is updated.
OwnershipTransferred(previous_owner: ContractAddress, new_owner: ContractAddress)
event
#Emitted when the ownership is transferred.
use openzeppelin_access::accesscontrol::AccessControlComponent;
Component that allows contracts to implement role-based access control mechanisms. Roles are referred to by their felt252
identifier:
const MY_ROLE: felt252 = selector!("MY_ROLE");
Roles can be used to represent a set of permissions. To restrict access to a function call, use assert_only_role
:
(...)
#[external(v0)]
fn foo(ref self: ContractState) {
self.accesscontrol.assert_only_role(MY_ROLE);
// Do something
}
Roles can be granted and revoked dynamically via the grant_role, grant_role_with_delay and revoke_role functions. Each role has an associated admin role, and only accounts that have a role’s admin role can call grant_role, grant_role_with_delay and revoke_role.
By default, the admin role for all roles is DEFAULT_ADMIN_ROLE
, which means that only accounts with this role will be able to grant or revoke other roles. More complex role relationships can be created by using set_role_admin.
The DEFAULT_ADMIN_ROLE
is also its own admin: it has permission to grant and revoke this role. Extra precautions should be taken to secure accounts that have been granted it.
Embeddable Mixin Implementations
AccessControlMixinImpl
Embeddable Implementations
AccessControlImpl
has_role(self, role, account)
get_role_admin(self, role)
grant_role(self, role, account)
revoke_role(self, role, account)
renounce_role(self, role, account)
AccessControlCamelImpl
hasRole(self, role, account)
getRoleAdmin(self, role)
grantRole(self, role, account)
revokeRole(self, role, account)
renounceRole(self, role, account)
AccessControlWithDelayImpl
SRC5Impl
Internal Implementations
InternalImpl
initializer(self)
assert_only_role(self, role)
is_role_effective(self, role, account)
resolve_role_status(self, role, account)
is_role_granted(self, role, account)
set_role_admin(self, role, admin_role)
_grant_role(self, role, account)
_grant_role_with_delay(self, role, account, delay)
_revoke_role(self, role, account)
Events
IAccessControl
RoleAdminChanged(role, previous_admin_role, new_admin_role)
RoleGranted(role, account, sender)
RoleRevoked(role, account, sender)
IAccessControlWithDelay
Embeddable functions
has_role(self: @ContractState, role: felt252, account: ContractAddress) → bool
external
#Returns whether account
can act as role
.
get_role_admin(self: @ContractState, role: felt252) → felt252
external
#Returns the admin role that controls role
. See grant_role and revoke_role.
To change a role’s admin, use set_role_admin.
get_role_status(self: @ContractState, role: felt252, account: ContractAddress) → RoleStatus
external
#Returns the account’s status for the given role.
The possible statuses are:
NotGranted
: the role has not been granted to the account.Delayed
: The role has been granted to the account but is not yet active due to a time delay.Effective
: the role has been granted to the account and is currently active.
grant_role(ref self: ContractState, role: felt252, account: ContractAddress)
external
#Grants role
to account
.
If account
had not been already granted role
, emits a RoleGranted event.
Requirements:
- the caller must have
role
's admin role.
May emit a RoleGranted event.
grant_role_with_delay(ref self: ContractState, role: felt252, account: ContractAddress, delay: u64)
external
#Attempts to grant role
to account
with the specified activation delay.
Requirements:
- The caller must have `role’s admin role.
- delay must be greater than 0.
- the
role
must not be already effective foraccount
.
May emit a RoleGrantedWithDelay event.
revoke_role(ref self: ContractState, role: felt252, account: ContractAddress)
external
#Revokes role
from account
.
If account
had been granted role
, emits a RoleRevoked event.
Requirements:
- the caller must have
role
's admin role.
May emit a RoleRevoked event.
renounce_role(ref self: ContractState, role: felt252, account: ContractAddress)
external
#Revokes role
from the calling account.
Roles are often managed via grant_role and revoke_role. This function’s purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced).
If the calling account had been revoked role
, emits a RoleRevoked event.
Requirements:
- the caller must be
account
.
May emit a RoleRevoked event.
supports_interface(self: @ContractState, interface_id: felt252) → bool
external
#getRoleAdmin(self: @ContractState, role: felt252) → felt252
external
#See get_role_admin.
grantRole(ref self: ContractState, role: felt252, account: ContractAddress)
external
#See grant_role.
revokeRole(ref self: ContractState, role: felt252, account: ContractAddress)
external
#See revoke_role.
renounceRole(ref self: ContractState, role: felt252, account: ContractAddress)
external
#See renounce_role.
Internal functions
initializer(ref self: ContractState)
internal
#Initializes the contract by registering the IAccessControl interface ID.
assert_only_role(self: @ContractState, role: felt252)
internal
#Validates that the caller can act as the given role. Otherwise it panics.
is_role_effective(self: @ContractState, role: felt252, account: ContractAddress) → bool
internal
#Returns whether the account can act as the given role.
The account can act as the role if it is active and the effective_from
time is before or equal to the current time.
If the effective_from
timepoint is 0, the role is effective immediately. This is backwards compatible with implementations that didn’t use delays but a single boolean flag.
resolve_role_status(self: @ContractState, role: felt252, account: ContractAddress) → RoleStatus
internal
#Returns the account’s status for the given role.
The possible statuses are:
NotGranted
: the role has not been granted to the account.Delayed
: The role has been granted to the account but is not yet active due to a time delay.Effective
: the role has been granted to the account and is currently active.
is_role_granted(self: @ContractState, role: felt252, account: ContractAddress) → bool
internal
#Returns whether the account has the given role granted.
The account may not be able to act as the role yet, if a delay was set and has not passed yet. Use is_role_effective
to check if the account can act as the role.
set_role_admin(ref self: ContractState, role: felt252, admin_role: felt252)
internal
#Sets admin_role
as role
's admin role.
Internal function without access restriction.
Emits a RoleAdminChanged event.
_grant_role(ref self: ContractState, role: felt252, account: ContractAddress)
internal
#Attempts to grant role
to account
. The function does nothing if role
is already effective for account
. If role
has been granted to account
, but is not yet active due to a time delay, the delay is removed and role
becomes effective immediately.
Internal function without access restriction.
May emit a RoleGranted event.
_grant_role_with_delay(ref self: ContractState, role: felt252, account: ContractAddress, delay: u64)
internal
#Attempts to grant role
to account
with the specified activation delay.
The role will become effective after the given delay has passed. If the role is already active (Effective
) for the account, the function will panic. If the role has been granted but is not yet active (being in the Delayed
state), the existing delay will be overwritten with the new delay
.
Internal function without access restriction.
Requirements:
- delay must be greater than 0.
- the
role
must not be already effective foraccount
.
May emit a RoleGrantedWithDelay event.
_revoke_role(ref self: ContractState, role: felt252, account: ContractAddress)
internal
#Revokes role
from account
.
Internal function without access restriction.
May emit a RoleRevoked event.
Events
RoleAdminChanged(role: felt252, previous_admin_role: ContractAddress, new_admin_role: ContractAddress)
event
#RoleGranted(role: felt252, account: ContractAddress, sender: ContractAddress)
event
#RoleGrantedWithDelay(role: felt252, account: ContractAddress, sender: ContractAddress, delay: u64)
event
#RoleRevoked(role: felt252, account: ContractAddress, sender: ContractAddress)
event
#