EOS

EOS账户权限与多重签名

简介

eosio的权限体系是一套适应性与复杂性都很高的,无论是在DAWN 4.0加入的eosio.code权限还是eosio.msig都可以帮协助我们实现一套相对完善的系统或DAPP;这里将重点介绍多重签名的实现。

账户与权限

经过之前的使用已经知道了账户是指EOS Account,名称只能是base32字符集,现版本在账户建立时默认两个权限OwnerActive;这里就产生了一些个问题:

我们转账或者其他操作的权限到底是属于私钥还是账户?

EOS Account是公开的仅当做一个地址、一个代号,作为权限与私钥拥有者的一个代称,无法作为token或者其他权限的持有者。(严格说私钥也不一定能拥有对应的权限)

我的EOS币等资产到底由谁支配?

既不是由某个EOS Account支配也不是由某个私钥支配。账户下的资产归属对应权限,谁能开启此权限,谁就能动用此资产。
就是说,你可能知道了某个账号的一个私钥,但是你却无法利用它获利,因为你可能值拥有了必要权限的一部分。

eosio是什么账户?

eosio是一个特权账户,它是在eos源码编译时就已经定义好的账号(可以修改);
eosio.systemeosio.bios智能合约必须使用特权账号部署。

EOS权限体系

先解释几个关键词:

  • perm_name 权限名称
  • parent 父级权限名称
  • weight 对应key权重
  • threshold 阈值;比如owner权限阈值为1,owner内的一个key权重为1,那此key就可以触发使用owner权限,小于阈值则不行。

使用eosjs查询一个账户可以得到以下内容:
(http://127.0.0.1:8888/v1/chain/get_account)

请看下表,在表中owner权限的阈值是2,但是下属的两个密钥权重都只有1,那如果要使用此权限owner权限则必须使用EOSkey1111和EOSkey2222,相加权重才会够阈值下限。
active权限也是两个密钥,其中EOSkey3333权重是2,就是说它可以单独使用active权限,但是相对的EOSkey4444则不行,必须得到EOSkey3333的同意;此外active是从属于owner的,所以能使用owner权限则一定能使用active。

PARENT-PERM PERMISSION ACCOUNT/KEY WEIGHT THRESHOLD
owner 2
EOSkey1111 1
EOSkey2222 1
owner active 2
EOSkey3333 2
EOSkey4444 1

在之前的我们执行转账调用合约都使用的是@active权限,因为我们active只有一个密钥,故它拥有了转账的权利。


再看下表,把key替换为其他的账号,比如下面这是user1的权限信息,那这个user1能独立做什么呢?什么都做不了,user1不具有操作owner与active所需要的权重,此账号如果要使用某种权限必然经过Account2222同意,没有它的同意,user1本身无法动用账户内所有的资产;但是Account2222可以独立使用user1的所有权限;简单说就是user1下的代币资产等等是完全归属于Account2222的;说到这里也就能明白eos体系内权限设计的重要性,它完全确定了资产、权利的归属,可以设计多Account、多key、多权限、多层级的复杂权限体系,借助这套体系可以玩出很多东西来。

PARENT-PERM PERMISSION ACCOUNT/KEY WEIGHT THRESHOLD
owner 2
EOSkey1111 1
@Account2222 2
owner active 2
@Account2222 2
EOSkey4444 1

这就是上边说到的账户下的资产归属对应权限,谁能开启此权限,谁就能动用此资产。

多重签名(Multiple Signatures)

利用上文所讲的eos账户权限机制我们可以实现多方签名共同操作同一个合约。这里就要使用到eosio.msig合约,此合约由官方提供,它负责我们多重签名的主要工作。

eosio.msig

eosio.msig中提出了一个proposal的概念,就暂时叫做提案吧;它本身并不是一个为了多重签名而生的东西,个人认为此合约它是为了提供权限申请的功能,举个例子:
创建token QQB指定所属用户userA,表明userA用户有权利给任何人派发QQB,然后issue发行货币给userB:

注意看命令2使用的权限为userA@active,就是说常规模式下你没有userA@active此权限的私钥就不可能给别人派发QQB token。换个角度分析,如果userB需要QQB,那他有两条路:

  1. 场外沟通,找到userA这个人跟他讲,让他提交这个命令2
  2. 想办法获取userA@active权限的私钥。第二个办法那只能各自想动脑筋去了。

很明显方式一有个缺陷,必须要场外沟通,而且交易命令还是由userA提交,userB只能从结果上得知命令是否成功或者有没有问题等。那eosio.msig合约就提供了这样一个权限申请:

  1. 由userB发起一比msig中的提案,内容为:想给userB发10个QQB,但是没有userA的权限,特发此提案;

  1. userA在线上对userB的test提案内容查询后,发现没有问题,将自己的active权限授予test提案表明可以执行;

  1. test提案得到了应有的权限后,它就可以被创始人userB直接执行,至此userB也就得到了他想要的10QQB。

此外eosio.msig合约还提供拒绝提案取消提案等操作。
另外使用此合约需要给部署此合约的账号授予特权:

通过msig我们可以向他人申请本不属于我们的权限,而且是在eos体系线上执行的,无须借助场外的手段请求他人的权限。

那么有了eosio.msig合约权限申请的功能,如何实现多重签名?

在文章的前半部有提到权限的组成是多样化的,可以多人多密钥共同管理权限,那也就是说,在提案审批的时候,由于权重问题就需要不同用户来进行审批,即多重签名

权限构建

接下来看一个实现多重签名的例子:

首先创建三个账户testaaaa1111testaaaa1112testaaaa1113

testaaaa1111构建有如下权限的账户:

PARENT-PERM PERMISSION ACCOUNT/KEY WEIGHT THRESHOLD
owner 1
EOSkeySDG….. 1
owner active 2
@testaaaa1112 1
@testaaaa1113 1

为了方便我们只使用修改active权限对owner不做修改,这里使用了eosjs实现:

调用http://127.0.0.1:8888/v1/chain/get_account可以查询到:

可以看出来testaaaa1111@actve权限的key已经被移除,并使用testaaaa1112testaaaa1113两个账号共同拥有此权限。


创建提案

以下内容均不使用owner权限

此时使用testaaaa1111转账等操作就会发现除了使用owner权限的key签名之外,连签名交易的key都不知道用什么。假设testaaaa1112想让testaaaa1111转出token,接下来使用eosio.msig合约的功能,调用合约中发起提案的propose方法:

eosio.msig合约使用了两个Multi-Index DB Table,名为proposalapprovals,分别记录了提案对应的交易与提案当前权限申请的状况。
可以在http://127.0.0.1:8888/v1/chain/get_table_rows

查询结果分别如下(这里查询的结果使用eosjs的查询结果可能有些许差异):

这里可以看到请求权限字段requested_approvals中有两个权限,已经提供权限provided_approvals没有值。


审批提案

接下来使用testaaaa1113账号进行一次审批提案:

使用http://127.0.0.1:8888/v1/chain/get_table_rows再次查询firstmsig11的进度:

基本上符合预期的结果,不过此requested_approvals字段表达的意思应该是:当前提案尚未取得的权限。

同样的使用刚才审批的操作将testaaaa1112@active也赋予给此提案。


执行提案

当两个必要权限都申请通过后,就可以执行此提案包含的交易内容,执行前记得看以下账户余额,我这里目前是testaaaa1111 199.0000 SYS; testaaaa1112 1.0000 SYS

当提案成功执行后会从Multi-Index DB Table中删除对应的记录。

至此多重签名就算是完成了。

.
.
.
.
.
.
【本文章出自NM1024.com,转载请注明作者出处。】

1 thought on “EOS账户权限与多重签名”

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据