WeIdentity 的多签及限量凭证的实现
在实际生产环境中,我们需要包括多签功能的更精准的权限控制。
在进行修改后,权限控制方案如下:
操作 | 一般DID | Authority Issuer | Commitee Member | Administrator |
---|---|---|---|---|
增删改 Adminnistrator | N | N | N | Y |
增删改 Committee Member | N | N | N | Y |
增删改 Authority Issuer | N | N | Y(可多签) | Y |
发行授权 CPT | N | Y | Y | Y |
我们通过对 AuthorityIssuer.sol
合约模块的升级,来实现多签的功能。
- 限量发行方向
在当前的流程中,我们会通过合约定义 CPT(Claim Protocol Type,凭证的声明类型),然后根据自定义的 CPT 模板发布 Credential(可验证的数字凭证)。
Crendential 和 ERC721 有类似之处,因此我们可以对发行 Credential 的流程进行升级,并加入新的合约,使其支持某一类型的 CPT 「限量发行」。例如某合格证书只发行一千个。
3. WeIdentity 合约结构与升级部分示意图
4. 权限控制(多签)的简介、接口描述与使用示范
AuthorityIssuerController
合约主要功能是对于 AuthorityIsser 角色的增加、删除、修改与查询,本次升级在增加中加入多签功能。
4.1 合约接口描述
-
addAuthorityIssuer 功能:新增 AuthorityIssuer
类型:原函数修改
参数:
变量名 类型 含义 addr Address 新增authorityIssuer的地址 attribBytes32 bytes32[16] 名字 attribInt int[16] 创建日期 accValue bytes 值(预留,目前无用) 返回值: 无
-
signTransaction 功能:实现多签功能
类型:新增函数
参数:
变量名 类型 含义 transactionId uint 需要进行多签的交易 id 返回值:无
-
getTxIDNeedMultiSigNum 功能:查询某交易还需要的签名数
类型:新增函数
参数:
变量名 类型 含义 transactionId uint 需要查询的交易id 返回值:
变量名 类型 含义 TxIDNeedMultiSigNum uint 查询的交易还需要的多签数量 -
getPendingTransactions 功能:获取当前所有需要被多签的交易
类型:新增函数
参数:无
返回值:
变量名 类型 含义 PendingTransactions uint[] 当前所有需要被多签的交易 -
setTxIdMultiSig 功能:设置某交易的多签数量
类型:新增函数
说明:因为该函数决定了新增 Authority Issuer 所需要的 Committee Member 数量,因此调用该函数需要 Administrator 权限【[见2](# 2 WeIdentity 升级点) 】。
参数:
变量名 类型 含义 transactionId uint 需要设置的交易id minNumber uint 要求的多签数量 返回值:无
4.2 合约使用示范
- 使用账户1部署合约
- 部署成功
- 测试新增 authorityIssuer 函数
其中,address 是新增为 authorityIssuer 的账户地址,attribBytes32 是名字,attribInt 是创建的日期.
- 填写参数,进行测试
transact后,该交易会被放入等待交易队列中,结果返回的交易序号为3。
- 测试查询等待队列函数
由于上述交易逻辑上会被保存进等待队列,因此这里我们去查看一下等待队列中是否真正被放入了该交易:
查询结果与逻辑无误。
- 设置多签要求
在多签之前,我们需要先为该等待交易设置多签数量,若不设置,则无法进行多签,这里我们为上述等待交易设置多签限制为2。
- 测试多签函数
设置完成后,我们使用当前账户(具备权限)对上述交易序号为3的交易进行多签:
结果返回签名成功,我们再切换其他具有权限的账户进行签名,这里是否具有权限是通过这段代码进行判断。
if(!roleController.checkPermission(tx.origin,roleController.MODIFY_AUTHORITY_ISSUER())) { return; }
使用第二个有权限的账户签名成功,由于已满足多签要求,因此新增成功:
5. 限量 CPT 的简介、接口描述与使用示范
1)CredentialController
为全新合约,主要功能为:
- 声明某 Id 的 Cpt 的 Credential 的发行数量,并存储。
- 发行 Credential 时生成需要的 ID 号与随机数,并存储。
- 提供如下查询:
- 通过 CPT Id 查询某 CPT 类型的总数及已发行数量。
- 通过 Credential Id 查询某 Credential 的相应随机数。
2)EvidenceContract
为旧合约的升级,主要功能是凭证上链,目前对 createEvidence 函数进行增强,加入 creid 与 randNum 两个参数,以实现链上验证的目的。
流程从链下发行 Credential,然后再通过 evidence 进行链上存证,转变为更复杂的「链上限量声明 → 带验证的发行 → Credential 的合法性与限量 CPT 的总量 / 已发行量可链上查询」逻辑,以实现某一类型的 CPT 限量发行。
具体步骤描述如下:
-
部署包含 CredentialController合约的WeIdentity 升级合约。
-
发行CPT(凭证模板)。
-
通过CredentialController 合约为 CPT 设置限额。
CPT 限量数额默认为零,也就是说如果 CPT 遵循限量发行流程(自然也可以选择传统流程),该 CPT 无法发行Credential,必须在设置后,方可发行。
-
查看某 CPT 限额。
-
发行基于CPT凭证模板的 Credential 凭证。
5.1. CredentialControlle r合约接收到 cpt_id ,查看该cpt是否超出限量。
5.2. 如果超出限量,则返回失败。
5.3. 如果没有超出限量,则通过CredentialController,credential_num(凭证计数器)+1,生成、存储并返会,credential_id与一个随机识别码rand_str,如299(第299个凭证)与b24136ac-58cd-48be-8822-c532d46297e5。
5.4. 链下基于credential_id,rand_str与其它数据payload,共同组装未签名credential_unsigned。
5.5. 调用evidence合约进行链上存证。
5.6.查看 credential_unsigned的credential_id与随机识别码rand_str是否与5.3中存储的数据匹配。
5.7. 不匹配则发行失败。
5.8. 凭证发行方对credential_unsigned进行签名,生成credential,授予接收对象,一张限量Credential发行完毕。
5.1 合约接口描述
-
generateIdAndRandNum 功能:生成 credentialID 号与随机数
类型:新增函数
参数:
变量名 类型 含义 cptid uint 要使用的 cpt 的编号 返回值:
变量名 类型 含义 creid uint 生成的 credential 编号 randNum uint 生成的随机数 -
setLimit 功能:设置某类型cpt的可发行的限量数额
类型:新增函数
参数:
变量名 类型 含义 cptid uint 要使用的 cpt 的编号 limitNum uint 该类型cpt限量发行的额数 返回值:无
-
getCptLimitAndIssuedNum 功能:获取某类型 cpt 的可发行的限量数额与已发行 credential 的数量
类型:新增函数
参数:
变量名 类型 含义 cptid uint 要查询的 cpt 的编号 返回值:
变量名 类型 含义 limitNumber uint 查询的 cpt 类型的可发行限量数额 issuedNumber uint 查询的 cpt 类型的已发行 credential 的数量 -
getRandNumOfCreid 功能:获得某 credential 中的的随机数
类型:新增函数
参数:
变量名 类型 含义 creid uint 要查询的 credential 编号 返回值:
变量名 类型 含义 randNum uint 查询的credential的随机数 -
createEvidence 功能:存证上链
类型:原函数修改
参数:
变量名 类型 含义 hash string 查询存证的key sig string 发布存证的人的签名 extra string 任意额外数据 updated uint256 当前event的更新时间 creid uint 某类型的cpt编号(新增变量) randNum uint 随机数(新增变量) 返回值:
变量名 类型 含义 result uint 上链成功与否的反馈值
5.2 合约使用示范
- 部署CredentialController合约
- 为某类型cpt设置限量数额
CPT 限量数额默认为零,也就是说如果 CPT 遵循限量发行流程(自然也可以选择传统流程),该 CPT 无法「发行」Credential,必须在设置后,方可发行。
设置成功
- 查看某类型cpt限额
这里我们查询刚刚设置的cptid为1的类型的限额
结果为我们刚刚设置的限额1,以及当前已发行的credential数量为0
- 生成 Credential Id与随机数
填写cptid,基于该类型生成一对 credential Id 与随机数
生成成功,得到 credential Id 与随机数,该id与随机数一一匹配,用于后续 Evidence 上链时的合法检验。
- 部署 EvidenceContract 合约
将此前部署的CredentialController合约地址填入,进行部署
- 存证上链
其中creid为要上链的credential的id号,randNum 为此前发行 credential 时得到的与id号一一配对的随机数。
填写参数,randNum处先随意填一个randNum,由于不配对,因此结果返回为0,上链失败。
再填写配对的随机数,进行测试,结果返回为1,上链成功。
6. 总结与未来计划
-
对 Credential 限量功能进行进一步的完善
目前限量 Credential 的逻辑是 AuthorityIssuer 在发行 CPT 时进行限量声明。如果进一步,我们可以做到多个 Issuer 协商 Credential 总量,之后每个特定的 Issuer 有特定的份额。
-
对 Credential 功能进行进一步的增强
例如 Credential 间的联动。
-
更全面更细化的权限控制
- 可以在更多方面引入多签。
- 引入更细化的权限控制,以应对实际生产环境中的复杂场景。