练习:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract AccessControl {
event GrantRole(bytes32 indexed role, address indexed account);
event RevokeRole(bytes32 indexed role, address indexed account);
// 权限控制映射:role => account => bool
// 使用bytes32存储角色名称,比string节省空间。使用hash值(bytes32类型)代替字符串。
mapping (bytes32 => mapping (address => bool)) public roles;
// 角色名称
bytes32 public constant ADMIN = keccak256(abi.encodePacked("ADMIN"));
bytes32 public constant UESER = keccak256(abi.encodePacked("UESER"));
// 权限控制函数修改器
modifier OnlyRole(bytes32 _role) {
require(roles[_role][msg.sender], "not authorized");
_;
}
// 构造函数中赋予合约部署者ADMIN权限
constructor() {
_grantRole(ADMIN, msg.sender);
}
// 内部升级函数
function _grantRole(bytes32 _role, address _account) internal {
roles[_role][_account] = true;
// 编写习惯:修改状态需要触发事件
emit GrantRole(_role, _account);
}
// 外部升级函数
function grantRole(bytes32 _role, address _account) external OnlyRole(ADMIN) {
_grantRole(_role, _account);
}
// 内部撤销权限
function _revokeRole(bytes32 _role, address _account) internal {
roles[_role][_account] = false;
// 编写习惯:修改状态需要触发事件
emit RevokeRole(_role, _account);
}
// 外部撤销权限
function evokeRole(bytes32 _role, address _account) external OnlyRole(ADMIN) {
_revokeRole(_role, _account);
}
}