当前位置:首页 > 物联网 > 区块链
[导读] 简介 基于角色的访问控制是软件系统的安全需求,旨在为数百个用户提供访问。虽然这种需求通常在企业软件和操作系统中实现,但对以太坊区块链的处理并不多。 当将供应链设计为有向无环图时,

简介

基于角色的访问控制是软件系统的安全需求,旨在为数百个用户提供访问。虽然这种需求通常在企业软件和操作系统中实现,但对以太坊区块链的处理并不多。

当将供应链设计为有向无环图时,我们意识到需要动态地确定谁可以向图中的每个节点添加信息。从现实世界的角度来看,如果您拥有一家制造工厂,您可能希望装配线上的所有操作员都能够用他们自己的帐户记录他们已经组装了一个零件。

OpenZeppelin是我在Solidity开发中使用的金标准,它有一个roles.sol合同,用于在erc721.sol合同中实现诸如minter和burner等角色。不幸的是,这些实现不允许在运行时创建新角色,如果您想使用单独的角色控制对每个单独令牌的访问,则需要创建新角色。

本文旨在展示如何为以太坊区块链构建基于角色的访问控制系统。根据我们的要求从头开始编写RBAC合同,然后从OpenZeppelin中找到了相同想法的版本,它具有几乎相同的方法。为了可重用性,我尽可能地重构我的代码以遵循它们的命名法。

在以下各节中,我将介绍:

1. 我们进入访问系统的设计要求;

2. 智能合约的实施;

3. 测试案例;

4. 状态变换法的gas利用;

5. 还有一些完善的想法。

概念设计

我对RBAC系统的想法很简单。

1. 角色将由数字标识符标识,如Unix中的组。

2. 角色可以动态创建。

3. 每个角色存储用户的地址。

4. 每个角色都会有一个关联的第二个角色,这是唯一允许添加或删除用户的角色。

如果您是使用OpenZeppelin中的Roles.sol和RBAC.sol合同,则需要注意Roles.sol仅实现在角色内生效的操作,而在角色外部发生的操作在RBAC.sol或访问中实现/roles/*Role.sol收缩,包括在创建角色时存储角色的数据结构。

在我的实现中,我根据我们的用例做了一些决策:

· 角色结构中包含一个描述字符串,结构本身存储在一个数组中。数组中每个角色结构的位置用作标识符。有一种使用映射来存储角色,但我发现这里没有必要。

· 每个角色在实例化时接收我们指定为其管理角色的另一个角色的标识符,并且在实例化之后不能修改该角色。此管理员角色是唯一可以为此角色添加和删除承载者的角色。

出于安全性和一致性的原因,您可以从角色中删除承载,但没有方法可以从系统中完全删除角色。

pragma solidity ^0.5.0;

/**

* @title RBAC

* @author Alberto Cuesta Canada

* @noTIce Implements runTIme configurable Role Based Access Control.

*/

contract RBAC {

event RoleCreated(uint256 role);

event BearerAdded(address account, uint256 role);

event BearerRemoved(address account, uint256 role);

uint256 constant NO_ROLE = 0;

/**

* @noTIce A role, which will be used to group users.

* @dev The role id is its posiTIon in the roles array.

* @param description A description for the role.

* @param admin The only role that can add or remove bearers from

* this role. To have the role bearers to be also the role admins

* you should pass roles.length as the admin role.

* @param bearers Addresses belonging to this role.

*/

struct Role {

string description;

uint256 admin;

mapping (address =》 bool) bearers;

}

/**

* @notice All roles ever created.

*/

Role[] public roles;

/**

* @notice The contract constructor, empty as of now.

*/

constructor() public {

addRootRole(“NO_ROLE”);

}

/**

* @notice Create a new role that has itself as an admin.

* msg.sender is added as a bearer.

* @param _roleDescription The description of the role created.

* @return The role id.

*/

function addRootRole(string memory _roleDescription)

public

returns(uint256)

{

uint256 role = addRole(_roleDescription, roles.length);

roles[role].bearers[msg.sender] = true;

emit BearerAdded(msg.sender, role);

}

/**

* @notice Create a new role.

* @param _roleDescription The description of the role created.

* @param _admin The role that is allowed to add and remove

* bearers from the role being created.

* @return The role id.

*/

function addRole(string memory _roleDescription, uint256 _admin)

public

returns(uint256)

{

require(_admin 《= roles.length, “Admin role doesn‘t exist.”);

uint256 role = roles.push(

Role({

description: _roleDescription,

admin: _admin

})

) - 1;

emit RoleCreated(role);

return role;

}

/**

* @notice Retrieve the number of roles in the contract.

* @dev The zero position in the roles array is reserved for

* NO_ROLE and doesn’t count towards this total.

*/

function totalRoles()

public

view

returns(uint256)

{

return roles.length - 1;

}

/**

* @notice Verify whether an account is a bearer of a role

* @param _account The account to verify.

* @param _role The role to look into.

* @return Whether the account is a bearer of the role.

*/

function hasRole(address _account, uint256 _role)

public

view

returns(bool)

{

return _role 《 roles.length && roles[_role].bearers[_account];

}

/**

* @notice A method to add a bearer to a role

* @param _account The account to add as a bearer.

* @param _role The role to add the bearer to.

*/

function addBearer(address _account, uint256 _role)

public

{

require(

_role 《 roles.length,

“Role doesn‘t exist.”

);

require(

hasRole(msg.sender, roles[_role].admin),

“User can’t add bearers.”

);

require(

!hasRole(_account, _role),

“Account is bearer of role.”

);

roles[_role].bearers[_account] = true;

emit BearerAdded(_account, _role);

}

/**

* @notice A method to remove a bearer from a role

* @param _account The account to remove as a bearer.

* @param _role The role to remove the bearer from.

*/

function removeBearer(address _account, uint256 _role)

public

{

require(

_role 《 roles.length,

“Role doesn‘t exist.”

);

require(

hasRole(msg.sender, roles[_role].admin),

“User can’t remove bearers.”

);

require(

hasRole(_account, _role),

“Account is not bearer of role.”

);

delete roles[_role].bearers[_account];

emit BearerRemoved(_account, _role);

}

}

测试

我喜欢公开测试智能合约,既展示了操作案例,又能对代码的可靠性提供了一些信心。

Contract: RBAC

RBAC

✓ addRootRole creates a role.

✓ hasRole returns false for non existing roles.

✓ hasRole returns false for non existing bearerships.

✓ addRootRole adds msg.sender as bearer.

✓ addRole doesn’t add msg.sender with admin role.

✓ addBearer reverts on non existing roles.

✓ addBearer reverts on non authorized users.

✓ addBearer reverts if the bearer belongs to the role.

✓ addBearer adds a bearer to a role.

✓ removeBearer reverts on non existing roles.

✓ removeBearer reverts on non authorized users.

✓ removeBearer reverts if the bearer doesn‘t belong to the role.

✓ removeBearer removes a bearer from a role.

为了回应之前的反馈,我现在还使用eth-gas-reporter的gas使用报告。

结论

本文描述了一个基于智能合约角色的访问控制系统的实现,它具有以下属性:

1. 允许在系统运行时创建新角色。

2. 包括角色管理员的概念,允许添加和删除角色的成员。

3. 允许轻松确定所有现有角色及其承载。

4. 基于角色的访问控制实现起来并不一定复杂,但正如本文所示,需要考虑许多权衡和设计决策,这些决策与您的用户及其允许的操作密切相关 去设计。如果您决定复用RBAC系统的这种实现,我会很高兴,但我也鼓励您寻找并考虑其他选择。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭