合约中一般会有多种针对不同数据的操作:例如对于存证内容的增加、更新及查询,若不进行一套符合要求的权限控制,事实上整个合约在真实环境下是没有多少使用价值的。那么应当如何对合约的权限进行划分?我们针对Solidity语言来寻找其对应的解决方案。
一、通过地址标记解决方案
传统的数据库方式是将不同的接口进行区分标记,同时将不同角色所拥有的不同接口权限进行标记,存入数据库当中。Solidity由于本身语法能力限制不能实现较为复杂的功能。类似于Linux文件系统的操作权限,我们可以使用0和1来区分当前角色是否对该接口拥有操作权限,同时将值进行排序,组合出不同的uint代表不同的权限。例如:对当前存证内容的可更新权限及对当前存证内容可查询权限我们将其排序可以得到权限0、1、2、3四种不通过权限,二进制00、01、10和11,分别代表不可更新不可查询、不可更新可查询、可更新不可查询及可更新可查询这四种不同权限。当权限种类较少的情况下完全可以使用这种方式,用uint对不同权限值进行映射(得到权限uint字段)。之后我们对每个具体人(address)映射对应的权限字段【mapping(address => uint)】。对于一个存证内容,我们可能需要分配多个不同人物不同权限,因此不同地址可以对应不同权限,当前该存证内容应当包含拥有1、2、3三种不同权限的所有用户address,未出现address默认权限值为0。同时我们还可以对该存证内容某些权限进行开放例如:将查询权限完全开放,任何人都可以拥有查询权限即一个基础默认权限01,所有的address拥有的权限与该权限进行 | 的位运算操作得到真实操作权限。
设计数据结构:
uint count; //用以计数当前非0权限用户个数
mapping(uint => mapping(address => uint)) Priviledge; //通过映射方式来实现权限标记
使用该种方法的缺点是需要对每个用户权限进行分配,事实上也可以将分配权限这个任务也作为一个权限,分配给不同的用户进行操作【包括分配权限,去除权限等】,整体可能较为复杂。
二、通过密码解决方案
可以对当前查找及更新操作进行密码标记,使用不同密码代表拥有不同的权限,同时对于密码设置可修改操作。从使用上而言方便创建者仅仅只需要通过一次密码或少数密码就可以为多数角色进行权限分配,但是可能存在密码泄露及密码遗忘等不可控原因。主要还是看合约在具体使用时对于安全性的要求及是否会使用到账户等具体实现情况。
三、其他玩法
如密码加address绑定,这样子的好处是不同进行address的传递,直接由当前用户进行权限激活即可,一个密码仅仅只能使用一次,这里需要一个记录。