openzeppelin学习笔记 - 3

很多时候单一角色的缺陷管理是无法满足系统功能的需要,需要使用多角色进行管理,这个时候
Ownable.sol就无法满足这种需求,这时可以使用Role来实现。

在开始之前先来说说library,library一般是用来扩展solidity中的类型,可以在基础类型上扩展一些方法,如:SafeMath。当然可以以不是基础类型,比如自定义的结构体也可以。

openzeppelinRole就是基于一个Roleslibrary定义的。

需要注意的是libaray中的方法的第一个参数需要是你要扩展的那个类型。

Roleslibrary中定义了对角色进行添加账户和删除账户的方法:

结构体

  • 角色,包含了角色和账户的对应关系
1
2
3
struct Role {
mapping (address => bool) bearer;
}
方法

  • 用户添加角色
1
function add(Role storage role, address account) internal
  • 用户删除角色
1
function remove(Role storage role, address account) internal
  • 判断用户是否拥有该角色
1
function has(Role storage role, address account) internal view returns (bool)
代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
pragma solidity ^0.4.24;
/**
* @title Roles
* @dev Library for managing addresses assigned to a Role.
* @dev 管理账户是否有对应角色的类库
*/
library Roles {
struct Role {
mapping (address => bool) bearer;
}
/**
* @dev give an account access to this role
* @dev 给账户添加对应角色
*/
function add(Role storage role, address account) internal {
require(account != address(0));
require(!has(role, account));
role.bearer[account] = true;
}
/**
* @dev remove an account's access to this role
* @dev 删除账户对应角色
*/
function remove(Role storage role, address account) internal {
require(account != address(0));
require(has(role, account));
role.bearer[account] = false;
}
/**
* @dev check if an account has this role
* @return bool
* @dev 检查账户是否具有该角色
*/
function has(Role storage role, address account)
internal
view
returns (bool)
{
require(account != address(0));
return role.bearer[account];
}
}