14 address private _owner;
3import “../utils/EnumerableSet.sol”;
7library Roles {
93 * for more information.
29 * @dev Check if an account has this role.
44 */
183 function _grantRole(bytes3232
94 */
56 */
10 }
32 }
75 /**
30 * {revokeRole} functions. Each role has an associated admin role, and only
37 _burn(from, amount);
9 mapping (address => bool) bearer;
13contract Ownable is Context {
24 emit OwnershipTransferred(address(0), msgSender);
3import “@openzeppelin/contracts/ownership/Ownable.sol”;
166 *
Openzeppelin即将宣布的v3.0版本(当前处于Beta版)已终止Roles库,,转而利用名为AccessControl的abstract 智能合约。
46 return _msgSender() == _owner;
128 * If `account` had been granted `role`, emits a {RoleRevoked} event.
113 * event.
75 _owner = newOwner;
91 * you perform all queries on the same block. See the following
69 /**
5 * @dev Contract module which provides a basic access control mechanism, where
119 function grantRole(bytes32 role, address account) public virtual {
在ABAC中,为每个用户分派了一组主题属性,为每个资源分派了一组工具属性。中央会见节制机构界说有关需要执行哪些主题和工具属性的法则。
148 * event.
14 ERC20Detailed(“MyToken”, “MTKN”, 18)
47 mapping (bytes32 => RoleData) private _roles;
72 function _transferOwnership(address newOwner) internal {
161 * @dev Grants `role` to `account`.
23 function remove(Role storage role, address account) internal {
37 modifier onlyOwner() {
13}
87 * Role bearers are not sorted in any particular way, and their ordering may
110 * @dev Grants `role` to `account`.
16 require(!has(role, account), “Roles: account already has role”);
15 * “`
60 * @dev Emitted when `account` is revoked `role`.
53 *
147 * If the calling account had been granted `role`, emits a {RoleRevoked}
24 * require(hasRole(MY_ROLE, _msgSender()));
129 *
51 /**
167 * Requirements:
26
6 */
24 }
72 return _roles[role].members.contains(account);
88 * change at any point.
27 // Only minters can mint
21 * @dev Remove an account’s access to this role.
131 *
10 * `onlyOwner`, which can be applied to your functions to restrict their use to
26 function mint(address to, uint256 amount) public {
17 for (uint256 i = 0; i < minters.length; ++i) {
31 }
159
52 * @dev Emitted when `account` is granted `role`.
162 *
114 *
1pragma solidity ^0.5.0;
120 require(hasRole(_roles[role].adminRole, _msgSender()), “AccessControl: sender must be an admin to grant”);
6
50
41
18 _minters.add(minters[i]);
21 *
78 */
99 /**
79 function getRoleMemberCount(bytes32 role) public view returns (uint256) {
182
10 function specialThing() public onlyOwner {
代码5展示了AccessControl的实现。
48
127 *
100 * @dev Returns the admin role that controls `role`. See {grantRole} and
135 require(hasRole(_roles[role].adminRole, _msgSender()), “AccessControl: sender must be an admin to revoke”);
Limitations(范围性)
108
123 }
152 * – the caller must be `account`.
8 * @dev Contract module that allows children to implement role-based access
34 * that only accounts with this role will be able to grant or revoke other
66 _transferOwnership(newOwner);
9
32 function has(Role storage role, address account) internal view returns (bool) {
28 * @dev Returns the address of the current owner.
12 * in the external API and be unique. The best way to achieve this is by
34 // Only burners can burn
149 *
179 function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
22 */
138 }
25 }
140 /**
130 * Requirements:
20 * function call, use {hasRole}:
71 function hasRole(bytes32 role, address account) public view returns (bool) {
尽量这为大大都智能合约应用措施提供了精采的基本,但基于现有的脚色的会见节制(RBAC)系统使打点员可以或许在运行时动态地界说脚色。从这个意义上说,Roles智能合约是具有限制性的,因为在陈设之后无法界说脚色。
29
115 * Requirements:
5contract MyContract is Ownable {
43 * @dev Returns true if the caller is the current owner.
65 */
63 * – if using `revokeRole`, it is the admin role bearer
6 * there is an account (an owner) that can be granted exclusive access to
代码3展示了Roles智能合约的实施。与Ownable差异,Role不提供自界说会见修饰符。相反利用此库的智能合约必需在函数内部实现脚色要求。他们还必需为每个脚色界说Roles.Role范例状态变量。代码4展示了实现两个脚色的ERC20智能合约的示例:_burners和_minters。
19 }
与RBAC对比,这是一个更巨大且耗时的办理方案。可是对付大型应用措施和企业而言,它越发机动,因为它答允每个用户独占的各类权限。
在runtime,Ownable或Roles都不满意这些民众模式中的任何一种。假如需要建设新脚色,则需要发送新代码。这些体系布局不答允InfoSec打点员通过简朴的界面建设、更新或删除新脚色。
109 /**
Role-Based Access Control (RBAC)
3/**
39}
47 }
onlyOwner模式是智能合约中最常用、最容易实现的会见节制要领。
Attribute-Based Access Control (ABAC)
67
9 * control mechanisms.
139
4 * @title Roles
7/**
13 * using `public constant` hash digests:
133 */
56 function renounceOwnership() public onlyOwner {
23 * function foo() public {
169 * – this function can only be called from a constructor.
27 * “`
11 // only the owner can call specialThing()!
116 *
82
60
5import “@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol”;
4import “../utils/Address.sol”;
122 _grantRole(role, account);
77 * together with {getRoleMember} to enumerate all bearers of a role.
23 }
107 }
7 // anyone can call this normalThing()
160 /**
6 function normalThing() public {
90 * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
24 require(has(role, account), “Roles: account does not have role”);
146 *
11 * the owner.
68 /**
2
70 * @dev Transfers ownership of the contract to a new account (`newOwner`).
85 * value between 0 and {getRoleMemberCount}, non-inclusive.
170 */
代码1显示了Ownable智能合约的Openzeppelin实现。
65 function transferOwnership(address newOwner) public onlyOwner {
代码2展示了如安在子智能合约中实现此示例。
53 * NOTE: Renouncing ownership will leave the contract without an owner,
178 */
具有活泼用户基本的软件,出格是企业软件,本质上需要差异级此外会见。跟着组织的成长或萎缩,会见节制应用措施的打点员需要可以或许轻松添加和分派新脚色的本领。这些布局如今以基于脚色的会见节制(RBAC)和基于属性的会见节制(ABAC)的形式存在于软件中。
30 function owner() public view returns (address) {
50 * @dev Leaves the contract without owner. It will not be possible to call
89 *
27
23 _owner = msgSender;
97 }
会见节制是软件基本设施安详的根基要素。企业应用措施需要严格的法则来抉择谁可以做什么,这取决于每个用户的权限。可以说,智能合约中的会见节制需要更严格的审查,因为裂痕大概导致恶意参加者节制系统。 郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
22 _burners.add(burners[i]);
70 */
96 return _roles[role].members.at(index);
28 *
76 }
1pragma solidity ^0.5.0;
101 * {revokeRole}.
102 *
35 * roles. More complex role relationships can be created by using
73 require(newOwner != address(0), “Ownable: new owner is the zero address”);
15
61 *
29 * Roles can be granted and revoked dynamically via the {grantRole} and
49 /**
42 struct RoleData {
174 }
141 * @dev Revokes `role` from the calling account.
172 require(!address(this).isContract(), “AccessControl: roles cannot be setup after construction”);
26 }
33 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
71 */
22 address msgSender = _msgSender();
45 function isOwner() public view returns (bool) {
36
4
136
6
13 constructor(address[] memory minters, address[] memory burners)
42 /**
158 }
36 */
35 * @dev Throws if called by any account other than the owner.
幸运的是,我们正在尽力办理这一问题。
163 * If `account` had not been already granted `role`, emits a {RoleGranted}
173 _grantRole(role, account);
2
125 /**
40 using Address for address;
4import “@openzeppelin/contracts/token/ERC20/ERC20.sol”;
175
39 using EnumerableSet for EnumerableSet.AddressSet;
35 require(_burners.has(msg.sender), “DOES_NOT_HAVE_BURNER_ROLE”);
38 }
29 */
80 return _roles[role].members.length();
151 *
33 function burn(address from, uint256 amount) public {
20 */
5import “../GSN/Context.sol”;
15 function add(Role storage role, address account) internal {
36 * {_setRoleAdmin}.
13 * @dev Give an account access to this role.
38abstract contract AccessControl is Context {
104 */
8 using Roles for Roles.Role;
21 for (uint256 i = 0; i < burners.length; ++i) {
43 EnumerableSet.AddressSet members;
142 *
25 role.bearer[account] = false;
2
16 {
19 * Roles can be used to represent a set of permissions. To restrict access to a
7contract MyToken is ERC20, ERC20Detailed {
52 *
118 */
18 *
157 _revokeRole(role, account);
11
58
14 *
2
20
14 */
68
8 }
48
153 */
58 _owner = address(0);
1pragma solidity ^0.5.0;
12 }
17 * “`
17 role.bearer[account] = true;
26 * }
59 /**
111 *
144 * purpose is to provide a mechanism for accounts to lose their privileges
33
37 */
124
28 require(_minters.has(msg.sender), “DOES_NOT_HAVE_MINTER_ROLE”);
69 * @dev Returns `true` if `account` has been granted `role`.
98
62 * @dev Transfers ownership of the contract to a new account (`newOwner`).
留意:不发起您在出产应用措施中利用此办理方案,因为它仍处于测试阶段。
61 /**
41
121
31 return _owner;
164 * event. Note that unlike {grantRole}, this function doesn’t perform any
54 * thereby removing any functionality that is only available to the owner.
5 * @dev Library for managing addresses assigned to a Role.
9 * This module is used through inheritance. It will make available the modifier
67 }
63 * Can only be called by the current owner.
Access Control (Beta)
103 * To change a role’s admin, use {_setRoleAdmin}.
只要系统不需要新的脚色,RBAC主要通过Roles智能合约来满意。
57 emit OwnershipTransferred(_owner, address(0));
18 }
168 *
10 Roles.Role private _minters;
92 * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
77}
55 * bearer except when using {_setupRole}.
46
74 emit OwnershipTransferred(_owner, newOwner);
132 * – the caller must have “role“’s admin role.
11 Roles.Role private _burners;
36}
30 _mint(to, amount);
8 struct Role {
137 _revokeRole(role, account);
40 }
17
16 * bytes32 public constant MY_ROLE = keccak256(“MY_ROLE”);
27 /**
16 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
44 bytes32 adminRole;
32 *
7 * specific functions.
95 function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
145 * if they are compromised (such as when a trusted device is misplaced).
12 /**
38 require(isOwner(), “Ownable: caller is not the owner”);
117 * – the caller must have “role“’s admin role.
3import “@openzeppelin/contracts/access/Roles.sol”;
180 _roles[role].adminRole = adminRole;
它具有机动性,答允智能合约界说所需的尽大概多的脚色,但这将require语句的实现留给了智能合约。由于未提供自界说会见修饰符,因此在某种水平上低落了可读性,而且增加了引入编码错误的大概性。可是没有什么能阻止智能合约实现包括require语句的自界说会见修饰符。
25 * …
这些当前的办理方案在陈设智能合约之前提供了脚色的机动性。由于脚色取决于硬编码法则,因此不支持动态建设的脚色。这很是适合在已知的内部智能合约之间提供会见节制,但它不能提供与现代面向用户的会见节制软件相当的机动性。
54 * `sender` is the account that originated the contract call, an admin role
11 * Roles are referred to by their `bytes32` identifier. These should be exposed
156
143 * Roles are often managed via {grantRole} and {revokeRole}: this function’s
81 }
假如Ownable仅限于一个打点员,则Openzeppelin的Roles库可以界说多个脚色。
64 * – if using `renounceRole`, it is the role bearer (i.e. `account`)
35 }
39 _;
57 event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
33 require(account != address(0), “Roles: account is the zero address”);
9
126 * @dev Revokes `role` from `account`.
8 *
177 * @dev Sets `adminRole` as “role“’s admin role.
106 return _roles[role].adminRole;
19
155 require(account == _msgSender(), “AccessControl: can only renounce roles for self”);
83 /**
176 /**
31 * accounts that have a role’s admin role can call {grantRole} and {revokeRole}.
150 * Requirements:
在RBAC中,每个用户都被分派了一个脚色,每个脚色都具有一组权限,而且只要他们的脚色具有正确的权限,用户就可以会见资源。
112 * If `account` had not been already granted `role`, emits a {RoleGranted}
12
Only Owner
62 * `sender` is the account that originated the contract call:
34 /**
73 }
12 */
171 function _setupRole(bytes32 role, address account) internal virtual {
74
165 * checks on the calling account.
45 }
64 */
15 public
55 */
4/**
本文先容现有的智能合约会见节制模式,并提出了RBAC和基于属性的会见节制(ABAC)智能合约的界说。
105 function getRoleAdmin(bytes32 role) public view returns (bytes32) {
86 *
30 * @return bool
1pragma solidity ^0.5.0;
19 * @dev Initializes the contract setting the deployer as the initial owner.
49 bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
154 function renounceRole(bytes32 role, address account) public virtual {
21 constructor () internal {
76 * @dev Returns the number of accounts that have `role`. Can be used
181 }
3import “../GSN/Context.sol”;
18 /**
84 * @dev Returns one of the accounts that have `role`. `index` must be a
31 */
2
51 * `onlyOwner` functions anymore. Can only be called by the current owner.
20 /**
该模式假定智能合约只有一个打点员,并使打点员可以将所有权转移到另一个地点。扩展Ownable智能合约答允子智能合约利用onlyOwner自界说修饰符界说函数。这些函数要求事务的发送者是单一打点员。
66 event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
10 *
如今智能合约中仅存有简朴形式的静态会见节制。最常见的是onlyOwner模式。另一个是Openzeppelin的“脚色”智能合约,该智能合约可以在陈设之前界说脚色。
Roles
134 function revokeRole(bytes32 role, address account) public virtual {
22 * “`
28 /**
1pragma solidity ^0.6.0;
59 }
25