美文网首页
Quorum介绍(三):Quorum权限体系

Quorum介绍(三):Quorum权限体系

作者: Eliza_0512 | 来源:发表于2019-12-16 18:22 被阅读0次

    本节详细介绍可以参考官方文档

    https://docs.goquorum.com/en/latest/Permissioning/Overview/

    Quorum目前的许可系统只限于节点等级的许可,只有在permission-nodes.json文件中定义的节点才能够加入网络。这个准许模型已经要被优化成基于智能合约的授权许可模型,新模型在管理节点、账户和账户权限管理上都有一定灵活度,整体框架模型如下图所示

    PermissionsModel.png

    在优化模型结构图中,一个网络聚合了一群组织。网络层级有网络管理员账号,网络管理员可以提议和投票新组织加入网络,也可以指定某个账号为机构管理员账号。

    机构管理员账号可以创建机构内角色、子机构、为自己机构下的账号赋予某种角色的功能,指定某个节点为本机构节点。子机构也可以创建自己的角色、子机构、节点。。。机构管理账号在机构层面管理和控制各项行为活动。父级机构管理原可以创建管理员角色,并将该角色的功能赋予其他账号。

    sampleNetwork.png

    一、智能合约设计

    Github智能合约文件地址

    ContractDesign.png

    Quorum权限系统智能合约的设计遵循Proxy-Implementation-Storage pattern(代理-实现-存储 模式),采用该模式可以保证及时业务逻辑层改变,也不会影响数据存储层和接口层的。智能合约的具体描述如下:

    • PermissionsUpgrade.sol存储implementation合约的地址,这份合约地址只有guardian账户可以操作改变

    • PermissionsInterface.sol接口定义,不含任何业务逻辑,会将接收到的请求转发给业务合约

    • PermissionsImplementation.sol包含所有授权系统的操作逻辑。只接收在 PermissionsUpgradable.sol 中定义的接口请求,并根据相应操作和对应的存储合约交互

    • OrgManager.sol存储机构和子机构信息,只接受来自 PermissionsUpgrade.sol合约中定义的implementation合约地址的请求

    • AccountManager.sol存储所有账户相关的信息,包括账户和组织和归属关系,一个账户地址有哪些权限等。同时也存储一个账号的状态:PendingApproval, Active, Inactive, Suspended, Blacklisted or Revoked

    • NodeManager.sol存储所有和节点相关的数据,包括节点和机构、子机构的关系,节点的状态: PendingApproval, Approved, Deactivated or Blacklisted

    • RoleManager.sol同样只接收在 PermissionsUpgrdable.sol定义的implementation合约的请求。 存储角色和组织的关系。角色能够包括的权限如下:

      • Readonly只读权限
      • Transact 只能交易,不能部署合约
      • ContractDeploy 可以交易,也可以部署合约
      • FullAccess 全权限

      如果一个角色被撤销,那么所有被赋予这个角色的账户都会失去角色原有的权限。

    • VoterManager.sol存储网络管理员信息。在创建网络时会预先定义一系列的网路管理员账号,这些账号都会被记录在本合约中。一旦网络层级有需要投票的事件发生,投票事件也会被记录在本合约中。

    <a name='init'>二、权限模型的部署</a>

    • 部署网络初始节点
    • 部署PermissionsUpgradable.sol合约。部署该合约时,作为参数需要指定一个guardian账号地址
    • 部署剩余的合约。部署剩余合约的时候都需要PermissionsUpgradable.sol合约地址作为部署参数
    • 所有合约部署完成后,按以下格式创建permission-config.json文件
    {
        "upgradableAddress": "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
        "interfaceAddress": "0x4d3bfd7821e237ffe84209d8e638f9f309865b87",
        "implAddress": "0xfe0602d820f42800e3ef3f89e1c39cd15f78d283",
        "nodeMgrAddress": "0x8a5e2a6343108babed07899510fb42297938d41f",
        "accountMgrAddress": "0x9d13c6d3afe1721beef56b55d303b09e021e27ab",
        "roleMgrAddress": "0x1349f3e1b8d71effb47b840594ff27da7e603d17",
        "voterMgrAddress": "0xd9d64b7dc034fafdba5dc2902875a67b5d586420",
        "orgMgrAddress" : "0x938781b9796aea6376e40ca158f67fa89d5d8a18",
        "nwAdminOrg": "ADMINORG",
        "nwAdminRole" : "ADMIN",
        "orgAdminRole" : "ORGADMIN",
        "accounts":["0xed9d02e382b34818e88b88a309c7fe71e65f419d", "0xca843569e3427144cead5e4d5999a3d0ccf92b8e"],
        "subOrgBreadth" : 3,
        "subOrgDepth" : 4
    }
    
    • 使用guardian account调用PermissionsUpgradable.sol的init服务

      • 使用geth加载以下内容

        ac = eth.accounts[0];
        web3.eth.defaultAccount = ac;
        var abi = [{"constant":true,"inputs":[],"name":"getPermImpl","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_proposedImpl","type":"address"}],"name":"confirmImplChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getGuardian","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPermInterface","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_permInterface","type":"address"},{"name":"_permImpl","type":"address"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_guardian","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}];
        var upgr = web3.eth.contract(abi).at("0x1932c48b2bf8102ba33b4a6b545c32236e342f34"); // address of the upgradable contracts
        var impl = "0xfe0602d820f42800e3ef3f89e1c39cd15f78d283" // address of the implementation contracts
        var intr = "0x4d3bfd7821e237ffe84209d8e638f9f309865b87" // address of the interface contracts
        
      • 执行 upgr.init(intr, impl, {from: <guardian account>, gas: 4500000})

    • 关闭所有geth节点,并将permission-config.json文件拷贝进每个节点的data文件夹下

    • 将所有geth节点以 --permissioned 方式启动

    三、API文档

    参见 [https://docs.goquorum.com/en/latest/Permissioning/Permissioning%20apis/](https://docs.goquorum.com/en/latest/Permissioning/Permissioning apis/)

    四、使用方法

    1 初始化网络

    具体操作方法可以参照本章第二节权限模型的部署

    • 假设初始节点的配置文件static-nodes.json的内容如下:

      [
          "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0",
          "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0",
          "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0",
          "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0"
      ]
      
    • 网络的权限配置如下

      > quorumPermission.orgList
      [{
          fullOrgId: "ADMINORG",
          level: 1,
          orgId: "ADMINORG",
          parentOrgId: "",
          status: 2,
          subOrgList: null,
          ultimateParent: "ADMINORG"
      }]
      > quorumPermission.getOrgDetails("ADMINORG")
      {
        acctList: [{
            acctId: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
            isOrgAdmin: true,
            orgId: "ADMINORG",
            roleId: "ADMIN",
            status: 2
        }, {
            acctId: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e",
            isOrgAdmin: true,
            orgId: "ADMINORG",
            roleId: "ADMIN",
            status: 2
        }],
        nodeList: [{
            orgId: "ADMINORG",
            status: 2,
            url: "enode://72c0572f7a2492cffb5efc3463ef350c68a0446402a123dacec9db5c378789205b525b3f5f623f7548379ab0e5957110bffcf43a6115e450890f97a9f65a681a@127.0.0.1:21000?discport=0"
        }, {
            orgId: "ADMINORG",
            status: 2,
            url: "enode://7a1e3b5c6ad614086a4e5fb55b6fe0a7cf7a7ac92ac3a60e6033de29df14148e7a6a7b4461eb70639df9aa379bd77487937bea0a8da862142b12d326c7285742@127.0.0.1:21001?discport=0"
        }, {
            orgId: "ADMINORG",
            status: 2,
            url: "enode://5085e86db5324ca4a55aeccfbb35befb412def36e6bc74f166102796ac3c8af3cc83a5dec9c32e6fd6d359b779dba9a911da8f3e722cb11eb4e10694c59fd4a1@127.0.0.1:21002?discport=0"
        }, {
            orgId: "ADMINORG",
            status: 2,
            url: "enode://28a4afcf56ee5e435c65b9581fc36896cc684695fa1db83c9568de4353dc6664b5cab09694d9427e9cf26a5cd2ac2fb45a63b43bb24e46ee121f21beb3a7865e@127.0.0.1:21003?discport=0"
        }],
        roleList: [{
            access: 3,
            active: true,
            isAdmin: true,
            isVoter: true,
            orgId: "ADMINORG",
            roleId: "ADMIN"
        }],
        subOrgList: null
      }
      

    2 提议新组织加入网络

    一旦网络部署完成以后,网络管理员账号可以提议一个新的组织加入网络。网络中所有的管理员账号会对这件事进行投票,投票通过后新组织被允许加入网络。

    具体操作执行可以查看API文档中的proposingapproving 操作

    具体步骤示意可以查看官方文档说明

    https://docs.goquorum.com/en/latest/Permissioning/Usage/#proposing-a-new-organization-into-the-network

    步骤

    1. 提议
    2. 查看提议的组织状态
    3. 投票
    4. 投票结果超过半数,同意新组织节点加入
    5. 新组织的节点加入网络。如果当前网络使用的是raft共识,需要注意,在新组织节点加入网络时要确保:
      1. 新的节点在raft层已经被添加为peer raft.addPeer(<<enodeId>>)
      2. 根据上一步获得的raft peer id,使用geth--raftjoinexisting模式启动新节点

    3 组织管理员管理和准入许可

    > quorumPermission.addSubOrg("ORG1", "SUB1", "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0", {from: eth.accounts[0]})
    "Action completed successfully"
    > quorumPermission.getOrgDetails("ORG1.SUB1")
    {
      acctList: null,
      nodeList: [{
          orgId: "ORG1.SUB1",
          status: 2,
          url: "enode://239c1f044a2b03b6c4713109af036b775c5418fe4ca63b04b1ce00124af00ddab7cc088fc46020cdc783b6207efe624551be4c06a994993d8d70f684688fb7cf@127.0.0.1:21006?discport=0"
      }],
      roleList: null,
      subOrgList: null
    }
    

    添加子机构并不是强制性的,如果机构管理员想为新创建的子机构添加一个管理账号,那么机构管理员首先需要

    1. 创建一个具有isAdmin权限的角色,并赋予子机构下某个账户这个角色 API
    2. 将新建的角色赋予子机构的账号

    需要注意的一点,上级机构拥有本机构和自己子机构的所有管理权限,而子机构管理员只拥有自己组织的管理权限。

    4 暂停某个机构

    1. 网络管理员(Network Admin) 提议修改某个组织的状态为“暂时关闭”
    2. 所有网络管理员针对此条提议进行投票

    5 组织层/网络层管理权限的授予

    在某些情况下,我们可以一个账号同时具有机构管理员的权限和网络管理员的权限。同样也是需要进过两个步骤

    1. 提议
    2. 投票

    相关文章

      网友评论

          本文标题:Quorum介绍(三):Quorum权限体系

          本文链接:https://www.haomeiwen.com/subject/xeidnctx.html