WeIdentity 源码分析 | 狗哥解码
RoleController 权限控制
> 本文来自「利牧羊」的投稿,(・ω・)ノ > ## 合约总览 > [WeIdentity 源码分析 | 狗哥解码(一)](https://learnblockchain.cn/article/807) > 在上一篇的合约分析中,我们分析了 WeIDContract 部分,该合约由于不依赖于其他模块,因此是我们分析整个合约的良好切入点。 ![1](https://img.learnblockchain.cn/2020/04/27_/991587124.png) 同样,除了WeIDContract外,我们可以从架构图中发现RoIeController同样是不依赖于其他模块,因此RoIeController将作为我们第二个分析的合约。 ``` pragma solidity ^0.4.4; /* * Copyright© (2018-2019) WeBank Co., Ltd. * * This file is part of weidentity-contract. * * weidentity-contract is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * weidentity-contract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with weidentity-contract. If not, see <https://www.gnu.org/licenses/>. */ /** * @title RoleController * This contract provides basic authentication control which defines who (address) * belongs to what specific role and has what specific permission. */ contract RoleController { /** * The universal NO_PERMISSION error code. */ uint constant public RETURN_CODE_FAILURE_NO_PERMISSION = 500000; /** * Role related Constants. */ uint constant public ROLE_AUTHORITY_ISSUER = 100; uint constant public ROLE_COMMITTEE = 101; uint constant public ROLE_ADMIN = 102; /** * Operation related Constants. */ uint constant public MODIFY_AUTHORITY_ISSUER = 200; uint constant public MODIFY_COMMITTEE = 201; uint constant public MODIFY_ADMIN = 202; uint constant public MODIFY_KEY_CPT = 203; mapping (address => bool) private authorityIssuerRoleBearer; mapping (address => bool) private committeeMemberRoleBearer; mapping (address => bool) private adminRoleBearer; function RoleController() public { authorityIssuerRoleBearer[msg.sender] = true; adminRoleBearer[msg.sender] = true; committeeMemberRoleBearer[msg.sender] = true; } /** * Public common checkPermission logic. */ function checkPermission( address addr, uint operation ) public constant returns (bool) { if (operation == MODIFY_AUTHORITY_ISSUER) { if (adminRoleBearer[addr] || committeeMemberRoleBearer[addr]) { return true; } } if (operation == MODIFY_COMMITTEE) { if (adminRoleBearer[addr]) { return true; } } if (operation == MODIFY_ADMIN) { if (adminRoleBearer[addr]) { return true; } } if (operation == MODIFY_KEY_CPT) { if (authorityIssuerRoleBearer[addr]) { return true; } } return false; } /** * Add Role. */ function addRole( address addr, uint role ) public { if (role == ROLE_AUTHORITY_ISSUER) { if (checkPermission(tx.origin, MODIFY_AUTHORITY_ISSUER)) { authorityIssuerRoleBearer[addr] = true; } } if (role == ROLE_COMMITTEE) { if (checkPermission(tx.origin, MODIFY_COMMITTEE)) { committeeMemberRoleBearer[addr] = true; } } if (role == ROLE_ADMIN) { if (checkPermission(tx.origin, MODIFY_ADMIN)) { adminRoleBearer[addr] = true; } } } /** * Remove Role. */ function removeRole( address addr, uint role ) public { if (role == ROLE_AUTHORITY_ISSUER) { if (checkPermission(tx.origin, MODIFY_AUTHORITY_ISSUER)) { authorityIssuerRoleBearer[addr] = false; } } if (role == ROLE_COMMITTEE) { if (checkPermission(tx.origin, MODIFY_COMMITTEE)) { committeeMemberRoleBearer[addr] = false; } } if (role == ROLE_ADMIN) { if (checkPermission(tx.origin, MODIFY_ADMIN)) { adminRoleBearer[addr] = false; } } } /** * Check Role. */ function checkRole( address addr, uint role ) public constant returns (bool) { if (role == ROLE_AUTHORITY_ISSUER) { return authorityIssuerRoleBearer[addr]; } if (role == ROLE_COMMITTEE) { return committeeMemberRoleBearer[addr]; } if (role == ROLE_ADMIN) { return adminRoleBearer[addr]; } } } ``` 此合约并不算太难理解,它主要就包含了四个功能,分别是:addRole、removeRole、checkPermission、checkRole。 而其中的Permission是由Role所决定的,具体权限划分看下图即可。 ![5](https://img.learnblockchain.cn/2020/04/27_/745440962.png) 了解完合约的大体内容后,我们就通过调试来具体分析下该合约内的各功能。 ## 在Remix上调试与分析各功能 打开Remix,这里我们使用的依旧是在线版Remix编译器。 >http://remix.ethereum.org/ **1)创建合约** ![2](https://img.learnblockchain.cn/2020/04/27_/653109670.png) **2)将RoleController.sol源码copy过去** **3)部署合约与调用** ![3](https://img.learnblockchain.cn/2020/04/27_/756748773.png) 部署完成之后,我们就可以开始对各功能进行调用了。 ![4](https://img.learnblockchain.cn/2020/04/27_/771299748.png) **4)CheckPermission** 我们按照代码的书写顺序,首先来分析下checkPermission函数。 ``` function checkPermission( address addr, uint operation ) public constant returns (bool) { if (operation == MODIFY_AUTHORITY_ISSUER) { if (adminRoleBearer[addr] || committeeMemberRoleBearer[addr]) { return true; } } if (operation == MODIFY_COMMITTEE) { if (adminRoleBearer[addr]) { return true; } } if (operation == MODIFY_ADMIN) { if (adminRoleBearer[addr]) { return true; } } if (operation == MODIFY_KEY_CPT) { if (authorityIssuerRoleBearer[addr]) { return true; } } return false; } ``` 从该函数的代码片段里可以看出,它做的主要工作其实就是接收两个参数:address、operation,然后再去判断该address所代表的role是否具备operation所代表的权限。 下面我们就实际调用一下。 我们将部署合约时所用的地址填入,再从200、201、202、203中随意选一个数字填入。(四个数字代表着不同权限) ![6](https://img.learnblockchain.cn/2020/04/27_/767044097.png) 然后点击call,来调用一下。 ![7](https://img.learnblockchain.cn/2020/04/27_/790368190.png) 调用之后,结果是true。为什么这里是true呢?原因则在于代码最上面的构造函数。 ![8](https://img.learnblockchain.cn/2020/04/27_/672605472.png) 这里我们去修改一下构造函数,把true全部改为false,再来重新部署一下,然后看一下调用结果。 ![9](https://img.learnblockchain.cn/2020/04/27_/564782356.png) 这时候调用结果就变成了false,也就代表着部署合约时的地址没有该权限。 **5)AddRole** 接下来我们就再来看一下addRole这个函数。 ``` function addRole( address addr, uint role ) public { if (role == ROLE_AUTHORITY_ISSUER) { if (checkPermission(tx.origin, MODIFY_AUTHORITY_ISSUER)) { authorityIssuerRoleBearer[addr] = true; } } if (role == ROLE_COMMITTEE) { if (checkPermission(tx.origin, MODIFY_COMMITTEE)) { committeeMemberRoleBearer[addr] = true; } } if (role == ROLE_ADMIN) { if (checkPermission(tx.origin, MODIFY_ADMIN)) { adminRoleBearer[addr] = true; } } } ``` 从代码片段的里,我们可以分析得到该函数的主要工作机制是:先判断我们要增加的是何种Role,然后再判断调用者是否具备增加该Role的权限,具备则增加。 分析完之后,我们依旧是进行调用来测试一下,由于这里增加新的Role需要权限,因此我们将前面修改的构造函数全部改回true,然后重新部署一下。 部署完成后,我们的这个address就拥有了所有的修改权限,这时,我们再通过https://vanity-eth.tk/ 生成一个新的以太坊地址。 生成之后,我们将该地址填入第一个参数,第二个参数从100、101、102中随意选一个。 ![10](https://img.learnblockchain.cn/2020/04/27_/618639416.png) 这里,我们第二个参数填的是100。 ![11](https://img.learnblockchain.cn/2020/04/27_/377826732.png) 然后我们点击transact,就生成了一条新的记录。 ![12](https://img.learnblockchain.cn/2020/04/27_/279583127.png) 我们再来通过前面的checkPermission测试一下是否添加成功了。 由于我们新增的role是authority类型,因此它应该具有的权限是MODIFY_KEY_CPT,所以我们的参数就填这两个。 ![13](https://img.learnblockchain.cn/2020/04/27_/122126870.png) 返回结果为true,说明我们新增成功了。 **6)CheckRole与RemoveRole** 剩下的CheckRole与RemoveRole由于它们和前面的CheckPermission与AddRole非常的相似,因此这里就不再做详细的阐述了。 ## 总结 到这里,RoleController这个合约我们就基本分析完成了,整体来讲,它还是非常的简单易读的,功能也相对简单明了。 在分析完成RoleController与Weldentity两个相对独立的模块后,接下来我们将会沿着链条向下剖析剩余模块。 ![slogan.jpeg](https://img.learnblockchain.cn/attachments/2020/04/eXZqIwPS5ea6e6d56234e.jpeg)
本文来自「利牧羊」的投稿,(・ω・)ノ
合约总览
WeIdentity 源码分析 | 狗哥解码(一)
在上一篇的合约分析中,我们分析了 WeIDContract 部分,该合约由于不依赖于其他模块,因此是我们分析整个合约的良好切入点。
同样,除了WeIDContract外,我们可以从架构图中发现RoIeController同样是不依赖于其他模块,因此RoIeController将作为我们第二个分析的合约。
pragma solidity ^0.4.4;
/*
* Copyright© (2018-2019) WeBank Co., Ltd.
*
* This file is part of weidentity-contract.
*
* weidentity-contract is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* weidentity-contract is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with weidentity-contract. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* @title RoleController
* This contract provides basic authentication control which defines who (address)
* belongs to what specific role and has what specific permission.
*/
contract RoleController {
/**
* The universal NO_PERMISSION error code.
*/
uint constant public RETURN_CODE_FAILURE_NO_PERMISSION = 500000;
/**
* Role related Constants.
*/
uint constant public ROLE_AUTHORITY_ISSUER = 100;
uint constant public ROLE_COMMITTEE = 101;
uint constant public ROLE_ADMIN = 102;
/**
* Operation related Constants.
*/
uint constant public MODIFY_AUTHORITY_ISSUER = 200;
uint constant public MODIFY_COMMITTEE = 201;
uint constant public MODIFY_ADMIN = 202;
uint constant public MODIFY_KEY_CPT = 203;
mapping (address => bool) private authorityIssuerRoleBearer;
mapping (address => bool) private committeeMemberRoleBearer;
mapping (address => bool) private adminRoleBearer;
function RoleController() public {
authorityIssuerRoleBearer[msg.sender] = true;
adminRoleBearer[msg.sender] = true;
committeeMemberRoleBearer[msg.sender] = true;
}
/**
* Public common checkPermission logic.
*/
function checkPermission(
address addr,
uint operation
)
public
constant
returns (bool)
{
if (operation == MODIFY_AUTHORITY_ISSUER) {
if (adminRoleBearer[addr] || committeeMemberRoleBearer[addr]) {
return true;
}
}
if (operation == MODIFY_COMMITTEE) {
if (adminRoleBearer[addr]) {
return true;
}
}
if (operation == MODIFY_ADMIN) {
if (adminRoleBearer[addr]) {
return true;
}
}
if (operation == MODIFY_KEY_CPT) {
if (authorityIssuerRoleBearer[addr]) {
return true;
}
}
return false;
}
/**
* Add Role.
*/
function addRole(
address addr,
uint role
)
public
{
if (role == ROLE_AUTHORITY_ISSUER) {
if (checkPermission(tx.origin, MODIFY_AUTHORITY_ISSUER)) {
authorityIssuerRoleBearer[addr] = true;
}
}
if (role == ROLE_COMMITTEE) {
if (checkPermission(tx.origin, MODIFY_COMMITTEE)) {
committeeMemberRoleBearer[addr] = true;
}
}
if (role == ROLE_ADMIN) {
if (checkPermission(tx.origin, MODIFY_ADMIN)) {
adminRoleBearer[addr] = true;
}
}
}
/**
* Remove Role.
*/
function removeRole(
address addr,
uint role
)
public
{
if (role == ROLE_AUTHORITY_ISSUER) {
if (checkPermission(tx.origin, MODIFY_AUTHORITY_ISSUER)) {
authorityIssuerRoleBearer[addr] = false;
}
}
if (role == ROLE_COMMITTEE) {
if (checkPermission(tx.origin, MODIFY_COMMITTEE)) {
committeeMemberRoleBearer[addr] = false;
}
}
if (role == ROLE_ADMIN) {
if (checkPermission(tx.origin, MODIFY_ADMIN)) {
adminRoleBearer[addr] = false;
}
}
}
/**
* Check Role.
*/
function checkRole(
address addr,
uint role
)
public
constant
returns (bool)
{
if (role == ROLE_AUTHORITY_ISSUER) {
return authorityIssuerRoleBearer[addr];
}
if (role == ROLE_COMMITTEE) {
return committeeMemberRoleBearer[addr];
}
if (role == ROLE_ADMIN) {
return adminRoleBearer[addr];
}
}
}
此合约并不算太难理解,它主要就包含了四个功能,分别是:addRole、removeRole、checkPermission、checkRole。
而其中的Permission是由Role所决定的,具体权限划分看下图即可。
了解完合约的大体内容后,我们就通过调试来具体分析下该合约内的各功能。
在Remix上调试与分析各功能
打开Remix,这里我们使用的依旧是在线版Remix编译器。
http://remix.ethereum.org/
1)创建合约
2)将RoleController.sol源码copy过去
3)部署合约与调用
部署完成之后,我们就可以开始对各功能进行调用了。
4)CheckPermission
我们按照代码的书写顺序,首先来分析下checkPermission函数。
function checkPermission(
address addr,
uint operation
)
public
constant
returns (bool)
{
if (operation == MODIFY_AUTHORITY_ISSUER) {
if (adminRoleBearer[addr] || committeeMemberRoleBearer[addr]) {
return true;
}
}
if (operation == MODIFY_COMMITTEE) {
if (adminRoleBearer[addr]) {
return true;
}
}
if (operation == MODIFY_ADMIN) {
if (adminRoleBearer[addr]) {
return true;
}
}
if (operation == MODIFY_KEY_CPT) {
if (authorityIssuerRoleBearer[addr]) {
return true;
}
}
return false;
}
从该函数的代码片段里可以看出,它做的主要工作其实就是接收两个参数:address、operation,然后再去判断该address所代表的role是否具备operation所代表的权限。
下面我们就实际调用一下。
我们将部署合约时所用的地址填入,再从200、201、202、203中随意选一个数字填入。(四个数字代表着不同权限)
然后点击call,来调用一下。
调用之后,结果是true。为什么这里是true呢?原因则在于代码最上面的构造函数。
这里我们去修改一下构造函数,把true全部改为false,再来重新部署一下,然后看一下调用结果。
这时候调用结果就变成了false,也就代表着部署合约时的地址没有该权限。
5)AddRole
接下来我们就再来看一下addRole这个函数。
function addRole(
address addr,
uint role
)
public
{
if (role == ROLE_AUTHORITY_ISSUER) {
if (checkPermission(tx.origin, MODIFY_AUTHORITY_ISSUER)) {
authorityIssuerRoleBearer[addr] = true;
}
}
if (role == ROLE_COMMITTEE) {
if (checkPermission(tx.origin, MODIFY_COMMITTEE)) {
committeeMemberRoleBearer[addr] = true;
}
}
if (role == ROLE_ADMIN) {
if (checkPermission(tx.origin, MODIFY_ADMIN)) {
adminRoleBearer[addr] = true;
}
}
}
从代码片段的里,我们可以分析得到该函数的主要工作机制是:先判断我们要增加的是何种Role,然后再判断调用者是否具备增加该Role的权限,具备则增加。
分析完之后,我们依旧是进行调用来测试一下,由于这里增加新的Role需要权限,因此我们将前面修改的构造函数全部改回true,然后重新部署一下。
部署完成后,我们的这个address就拥有了所有的修改权限,这时,我们再通过https://vanity-eth.tk/ 生成一个新的以太坊地址。
生成之后,我们将该地址填入第一个参数,第二个参数从100、101、102中随意选一个。
这里,我们第二个参数填的是100。
然后我们点击transact,就生成了一条新的记录。
我们再来通过前面的checkPermission测试一下是否添加成功了。
由于我们新增的role是authority类型,因此它应该具有的权限是MODIFY_KEY_CPT,所以我们的参数就填这两个。
返回结果为true,说明我们新增成功了。
6)CheckRole与RemoveRole
剩下的CheckRole与RemoveRole由于它们和前面的CheckPermission与AddRole非常的相似,因此这里就不再做详细的阐述了。
总结
到这里,RoleController这个合约我们就基本分析完成了,整体来讲,它还是非常的简单易读的,功能也相对简单明了。
在分析完成RoleController与Weldentity两个相对独立的模块后,接下来我们将会沿着链条向下剖析剩余模块。
区块链技术网。
- 发表于 2020-04-27 22:07
- 阅读 ( 1764 )
- 学分 ( 63 )
- 分类:FISCO BCOS
- 专栏:狗哥区块链精品内容集
评论