Can I dynamic create role with OpenZeppelin access control?

I'm learning RBAC on blockchain, by OpenZeppelin Accesscontrol library I can set roles before the contract is deployed.

contract MyToken is  AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(address minter) {
        _grantRole(MINTER_ROLE, minter);
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);

The role set in above contract is Minter_role, which is static.
My question is, how can I create a function to set roles after the contract is deployed? And if it's possible, is this idea useful?

Just like the following codes, although it fails to compile.

    function dynamicCreateRole(bytes32 roleName, string calldata roleString) public pure returns (bytes32)  {
        roleName = keccak256(roleString);
        return roleName;

Hey @Huowuge!

how can I create a function to set roles after the contract is deployed?

Access Control already exposes public functions for granting and revoking roles after the contract is deployed, so by inheriting from it (is AccessControl), your contract will have them.

Note that grantRole and revokeRole can be only called by the admin of the role.

The example you shared might work but is not necessary since the new roles can be computed of chain, and technically, any bytes32 is a valid role.

Hope this helps

Thanks for your reply. You mentioned "any bytes32 is a valid role", it makes me clear.

I actually want to create bytes32 role dynamically after the contract is deployed, and now I noticed that I can not do this. Maybe update the contract is the only approach to do that.

1 Like

I tried my best to finish the following codes. Could anyone check my code and give some advice? Is there any security problem? And could you please push some project code like this?

import "@openzeppelin/contracts/access/AccessControl.sol";

contract X is AccessControl {

    constructor() {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
    // dynamic role
    function _encodeString(string calldata stringEncoded) internal pure returns(bytes32) {
        return keccak256(bytes(stringEncoded));
    // admin call this function to grant dynamic role to certain address.
    function dynamicGrantRole(string calldata stringEncoded, address addressSpecific) public {
        grantRole(_encodeString(stringEncoded), addressSpecific);
    // caller of this function should input correct password. 
    function getDynamic(string calldata password) public view {
        require(hasRole(_encodeString(password), msg.sender));