uos.msig是uos的提案合约,同样也是cluos multisig命令调用的系统合约,可用于提案、通过/不通提案、执行多重签名交易等功能。由于涉及内容较多,介绍将分为上下两篇,上篇将围绕uos账户权限、cluos multisig命令的使用这几个方面进行介绍,下篇则会为大家介绍uosio.msig的源码实现。
一个账户最基本的权限owner和active是由公私钥对控制的,然而,eos丰富的权限控制方式,还允许我们将一个账户的权限,下放给其他账号户。比如下面的经典例子:
接下来我将演示如何调用,部署uosio多重签名来为介绍uos权限的应用
1, 我们首先用cluos创建3对密钥
root@shuai:~/eosdata/uostest1# cluos create key --to-console
Private key: 5JKmUzikdTDfvpfJUL1q2uRkMNo5fUKb1HBm3AWiFK2ia7JFn66
Public key: UOS77Y6GhSH1fyrjGMrxgzFgiVwZA3XAHeZ7LrzEP66spQttxhkT2
root@shuai:~/eosdata/uostest1# cluos create key --to-console
Private key: 5JYTkqtzroMESzEBQRJhVKekM1bWyVAPj5tTF6t3WEszZNguhMW
Public key: UOS79PopaMZKosycm8VQ9MxbKFusJnEpzfbk7BH73oQ9rUTiwuym5
root@shuai:~/eosdata/uostest1# cluos create key --to-console
Private key: 5JYTkqtzroMESzEBQRJhVKekM1bWyVAPj5tTF6t3WEszZNguhMW
Public key: UOS79PopaMZKosycm8VQ9MxbKFusJnEpzfbk7BH73oQ9rUTiwuym5
1, 我们分别用系统超级用户uosio创建3个账户shuaitest123、useratest123、userbtest123,每个账户分别使用上面的公私钥对,账号长度必须为12,短号需要竞拍。
root@shuai:~/uos/contracts/uosio.system# cluos system newaccount uosio --transfer shuaitest123 UOS77Y6GhSH1fyrjGMrxgzFgiVwZA3XAHeZ7LrzEP66spQttxhkT2 --stake-net "1.0000 UOS" --stake-cpu "1.0000 UOS" --buy-ram "12.0000 UOS"executed transaction: 74134f8456d6079db7d4e20f527ed5a21c25ef8b2cbd49838841a92366038065 344 bytes 1922 us
# uosio <= uosio::newaccount {"creator":"uosio","name":"shuaitest123","owner":{"threshold":1,"keys":[{"key":"UOS77Y6GhSH1fyrjGMrx...
# uosio <= uosio::buyram {"payer":"uosio","receiver":"shuaitest123","quant":"12.0000 UOS"}
# uosio.token <= uosio.token::transfer {"from":"uosio","to":"uosio.ram","quantity":"11.9400 UOS","memo":"buy ram"}
# uosio <= uosio.token::transfer {"from":"uosio","to":"uosio.ram","quantity":"11.9400 UOS","memo":"buy ram"}
# uosio.ram <= uosio.token::transfer {"from":"uosio","to":"uosio.ram","quantity":"11.9400 UOS","memo":"buy ram"}
# uosio.token <= uosio.token::transfer {"from":"uosio","to":"uosio.ramfee","quantity":"0.0600 UOS","memo":"ram fee"}
# uosio <= uosio.token::transfer {"from":"uosio","to":"uosio.ramfee","quantity":"0.0600 UOS","memo":"ram fee"}
# uosio.ramfee <= uosio.token::transfer {"from":"uosio","to":"uosio.ramfee","quantity":"0.0600 UOS","memo":"ram fee"}
# uosio <= uosio::delegatebw {"from":"uosio","receiver":"shuaitest123","stake_net_quantity":"1.0000 UOS","stake_cpu_quantity":"1....
# uosio.token <= uosio.token::transfer {"from":"uosio","to":"uosio.stake","quantity":"2.0000 UOS","memo":"stake bandwidth"}
# uosio <= uosio.token::transfer {"from":"uosio","to":"uosio.stake","quantity":"2.0000 UOS","memo":"stake bandwidth"}
# uosio.stake <= uosio.token::transfer {"from":"uosio","to":"uosio.stake","quantity":"2.0000 UOS","memo":"stake bandwidth"}
warning: transaction executed locally, but may not be confirmed by the network yet ]
账户 shuaitest23:
账户 useratest23:
账户 userbtest23:
将shuaitest123的owner权限交出,由useratest123和userbtest123的owner权限控制。每个权限的权重weight是1,而门槛threshold是2,即用shuaitest23的owner权限发送交易,需要useratest123和userbtest123进行多重签名才行。
root@shuai:~# cluos set account permission shuaitest123 owner '{"threshold":2, "keys":[], "accounts": [{"permission":{"actor":"useratest123","permission":"owner"},"weight":1},{"permission":{"actor":"userbtest123","permission":"owner"},"weight":1}]}' -p shuaitest123@owner
可以发现shuaitest123账户的owner权限变了,变为useratest123和userbtest123共有
同样按照
root@shuai:~# cluos set account permission shuaitest123 active '{"threshold":2, "keys":[], "accounts": [{"permission":{"actor":"useratest123","permission":"active"},"weight":1},{"permission":{"actor":"userbtest123","permission":"active"},"weight":1}]}' -p shuaitest123@active
可以更改账户的active权限,但本文没有用active去签名交易,所以不作更改了
UOS账户这一节,我们将shuaitest123账户的owner和active权限交给了useratest123和userbtest123账户,则shuaitest123账户原来的公私钥对就失效了,交易的发送需要useratest123和userbtest123账户授权。
额外提一句,主网启动后,超级节点们会将eosio账户的权限交给uosio.prods账户,而uosio.prods账户是由21个超级节点的账户联合控制的,需要15个节点联合签名才能使用uosio账户,可以避免拿管理员权限作恶的现象
下面,我们就要介绍cluos multisig命令如何调用uosio.msig合约进行提案、发送多重签名的交易。
1.useratest123发起一个转账提案,提案名是testtransfer,将shuaitest123账户中的10EOS转给useratest123保证shuaitest123账户有币
2. 给账户“shuaitest123”发行Token
现在我们已经创建了名为UOS的token,发行人可以向我们之前创建的shuaitest123帐户发行新的token。
我们使用序列化参数方式调用操作(或者使用命名参数方式)。
cluos push action uosio.token issue '[ "shuaitest123", "100.0000 UOS", "memo" ]' -p uosio
此时可以看到账户shuaitest123已经有钱了
这里多的2UOS是我们开始创建账号的时候就打了2UOS给shuaitest123
然后接下来开始我们的提案
cluos multisig propose testtransfer '[{"actor":"useratest123","permission":"owner"},{"actor":"userbtest123","permission":"owner"}]' '[{"actor":"shuaitest123","permission":"owner"}]' uosio.token transfer '{"from":"shuaitest123","to":"ueratest123","quantity":"10.0000 UOS","memo":"hello"}' -p useratest123
提安格式比较长,比较复杂。详细分析下cleos multisig propose命令参数:
- proposal_name:提案名
- requested_permissions:提案审批通过需要的权限,这里需要useratest123和userbtest123的owner权限
- trx_permission:提案执行需要的权限,需要shuaitest123的owner权限就能发起转账
- contract:提案调用的合约账户,转账使用uosio.token账户合约
- action:提案调用的合约方法,转账使用transfer方法
- data:具体数据
- proposer:提案发起人,useratest123发起
- proposal_expiration:提案的有效时间
cleos multisig review <proposer> <proposal_name>
这笔转账提案的交易中,memo字段就可以保存我们自己想要上传的文本
4. 查看提案审批情况,provided_approvals为空表示尚未审批,request_approvals表示需要哪些权限进行审批
cleos get table eosio.msig <proposer> approvals
可以查看所有useratest123这个账号提交的未被确认的提案记录
“provided_approvals”:列表为空,表示useratest123和userbtest123账户都还没用自己的owner权限签名通过提案。提案有时间限制,一段时间内两个账户未确认就会失效。
5. 通过提案
cluos multisig approve useratest123 testtransfer '{"actor": "useratest123", "permission": "owner"}' -p useratest123@owner
cluos multisig approve useratest123 testtransfer '{"actor": "userbtest123 ", "permission": "owner"}' -p userbtest123 @owner
使用两个账户之前要保证两个账户的公私钥导入到钱包中了。
cluos wallet import -n admin1 --private-key 5JYTkqtzroMESzEBQRJhVKekM1bWyVAPj5tTF6t3WEszZNguhMW
否则会报如下错误:
成功同意提案应该是这样:
这里useratest123同意后我们可以再看下"provided_approvals":列表是否为空
可以看到useratest123同意了,
两个账户都同意并且用owner权限签名了,则此提案通过。
5. 执行提案
cleos multisig exec <proposer> <proposal_name> -p 谁想执行都可以
这里我们用userbtest123账户来执行提案。
注意:执行提案的时候,可能出现未知错误,需要部署uosio.system系统合约,并开启提案合约的功能即可解决(具体原理会在介绍uos.system合约的时候介绍)
6.查询useratest123账户的余额
这里我们发现提案通过并执行了,为什么useratest123的余额没有变化呢?这是因为在2人拥有第3人的owner权限时,是不能发给这两人中某一人转钱的这种提案的。只要把钱转给其他用户就可以看到余额变化了