EOS智能合约之多重签名

1 多签名操作的概念

回想一下创建账户的命令:

Usage: cleos create account [OPTIONS] creator name OwnerKey [ActiveKey]

一个账户拥有Owner和Active权限。同时账户也能够自定义新的权限。所谓多签名,就是一个账户可以将它的权限指派给其它多个账户,一个操作只有得到这些授权用户签名而得到执行。多签名是加强账户安全性的一个方法。EOS的多签名是由智能合约eosio.msig来进行支持的。

2 多签名实施

创建3个账户并设置权限

首先创建3个key并导入到钱包:

~/eos$ cleos wallet keys
[
  "EOS5goTcdfs9DoaC1cNXSHuWqG6zZNNcnwrMdTqoFB8VuJEhK3yRz",
  "EOS5p4xfYuHqcKBypvMYqTyvvCTcv3fxijM7yedFYEWDSPbzVMRvY",
  "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
]

然后用这3个key分别创建3个账户jack、alice和bob。

查询jack账户的权限:

~/eos$ cleos get account jack
permissions: 
     owner     1:    1 EOS5goTcdfs9DoaC1cNXSHuWqG6zZNNcnwrMdTqoFB8VuJEhK3yRz
        active     1:    1 EOS5goTcdfs9DoaC1cNXSHuWqG6zZNNcnwrMdTqoFB8VuJEhK3yRz

我们打算将jack的Owner和Active权限按照下表授权给alice和bob:

ps:这里有权重weight和门槛threshold,对于owner权限,alice和bob的weight都是1,而threshold为2,则说明owner权限需要alice和bob一起签名操作才能够执行;对于active权限,alice和bob的weight都是1,而threshold为1,则说明active权限只需要alice或bob任何一个签名操作就能够执行。

我们先设置jack的owner权限:

cleos set account permission jack owner '{"threshold":2,"keys":[],"accounts":[{"permission":{"actor":"alice","permission":"owner"},"weight":1},{"permission":{"actor":"bob","permission":"owner"},"weight":1}],"waits":[]}' -p jack@owner
executed transaction: b9b14d39de24afc32a854252a4c5bae917d9efc669da3e772dfb1e494f74507c  248 bytes  5091 us
#         eosio <= eosio::updateauth            {"account":"jack","permission":"owner","parent":"","auth":{"threshold":2,"keys":[],"accounts":[{"per...
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

然后再设置jack的active权限:

~/eos$ cleos set account permission jack active '{"threshold":1,"keys":[],"accounts":[{"permission":{"actor":"alice","permission":"owner"},"weight":1},{"permission":{"actor":"bob","permission":"owner"},"weight":1}],"waits":[]}' owner -p jack@owner
executed transaction: 6c2ed86f680f11aec98d924a6a944f9d3844c7ef49df9129ca9f2bd195607955  264 bytes  397 us
#         eosio <= eosio::updateauth            {"account":"jack","permission":"active","parent":"owner","auth":{"threshold":1,"keys":[],"accounts":...
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

此时再查看jack账户的权限,可以看到和权限表一致:

~/eos$ cleos get account jack
permissions: 
     owner     2:    1 alice@owner, 1 bob@owner, 
        active     1:    1 alice@owner, 1 bob@owner, 

部署eosio.msig合约

我们先创建名为eosio.msig的账户:

~/eos$ cleos create account eosio eosio.msig EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV

然后用该账户来发布eosio.msig合约:

~/eos$ cleos set contract eosio.msig build/contracts/eosio.msig -p eosio.msig
Reading WAST/WASM from build/contracts/eosio.msig/eosio.msig.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 049b8cc33bf6462eaa3a7ddc1d01db549198bd045d10aa32888972ec20c9e929  8952 bytes  1320 us
#         eosio <= eosio::setcode               {"account":"eosio.msig","vmtype":0,"vmversion":0,"code":"0061736d010000000198011760017f0060047f7e7e7...
#         eosio <= eosio::setabi                {"account":"eosio.msig","abi":"0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650...
warning: transaction executed locally, but may not be confirmed by the network yet 

然后通过账户acctoken发布eosio.token智能合约,并创建名为EOS的代币。这些都完成以后向jack、alice和bob分别派发100个代币。

~/eos$ cleos push action acctoken issue '["jack","100.0000 EOS","memo"]' -p eosio
~/eos$ cleos push action acctoken issue '["alice","100.0000 EOS","memo"]' -p eosio
~/eos$ cleos push action acctoken issue '["bob","100.0000 EOS","memo"]' -p eosio

查询余额,3个账户余额都是100:

~/eos$ cleos get currency balance acctoken jack EOS
100.0000 EOS
~/eos$ cleos get currency balance acctoken alice EOS
100.0000 EOS
~/eos$ cleos get currency balance acctoken bob EOS
100.0000 EOS

发起多签名操作提案

假如jack不在,要想通过bob和alice两个人来审批本属于jack的操作,这就要比jack本人操作要麻烦一点,需要新建一个提案。这个提案让jack给bob发送25个代币,需要alice和bob一起用owner权限来签名。

~/eos$ cleos multisig propose nojack '[{"actor":"alice","permission":"owner"},{"actor":"bob","permission":"owner"}]' '[{"actor":"jack","permission":"owner"}]' acctoken transfer '{"from":"jack","to":"bob","quantity":"25.0000 EOS","memo":"test multisig"}' -p acctoken
executed transaction: 303275fe76711aebeddf99d8ed01086032c97d4e8f44c3f1c4038a7ec139fa7f  328 bytes  17925 us
#    eosio.msig <= eosio.msig::propose          {"proposer":"acctoken","proposal_name":"nojack","requested":[{"actor":"alice","permission":"owner"},...
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

multisig合约定义了两个数据表,其中一个approvals表就是记录了提案的审批状态。

~/eos$ cleos get table eosio.msig eosio.msig approvals
{
  "rows": [{
      "proposal_name": "nojack",
      "requested_approvals": [{
          "actor": "alice",
          "permission": "owner"
        },{
          "actor": "bob",
          "permission": "owner"
        }
      ],
      "provided_approvals": []
    }
  ],
  "more": false
}

可以看到现在有2个提案需要审批,放在requested_approvals中。

审批提案

alice审批通过提案:

~/eos$ cleos multisig approve eosio.msig nojack '{"actor":"alice","permission":"owner"}' -p alice@owner
executed transaction: 93a101ef6a131acba69028aa0599f6bcf4c3ab4bd66f5476b0f64bd0ec493737  216 bytes  433 us
#    eosio.msig <= eosio.msig::approve          {"proposer":"eosio.msig","proposal_name":"nojack","level":{"actor":"alice","permission":"owner"}}
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

bob审批提案:

~/eos$ cleos multisig approve eosio.msig nojack '{"actor":"bob","permission":"owner"}' -p bob@owner
executed transaction: 512edc5c7b30a7b97a9100a4a4f2fa63d7c741d0730e2134a09afdf195789bb9  216 bytes  372 us
#    eosio.msig <= eosio.msig::approve          {"proposer":"eosio.msig","proposal_name":"nojack","level":{"actor":"bob","permission":"owner"}}
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

提案都通过了,可以开始执行了:

~/eos$ cleos get table eosio.msig eosio.msig approvals{
  "rows": [{
      "proposal_name": "nojack",
      "requested_approvals": [],
      "provided_approvals": [{
          "actor": "alice",
          "permission": "owner"
        },{
          "actor": "bob",
          "permission": "owner"
        }
      ]
    }
  ],
  "more": false
}

执行提案

执行提案用命令:

~/eos$ cleos multisig exec eosio.msig nojack -p eosio.msig
Error 3090003: Provided keys, permissions, and delays do not satisfy declared authorizations
Ensure that you have the related private keys inside your wallet and your wallet is unlocked.

可是执行出错了,这是什么原因呢?原因就是multisig没有权限执行jack@owner许可,这是自然的。如果随便部署一个合约都能执行别的账户的许可,这就是天大的安全问题。所以我们需要给这个multisig一个系统权限。注意,我们现在用的自测的nodeos节点,部署的时候没有给它系统权限,主网和测试网络上的eosio.multisig合约都已经拥有了系统权限。

我们执行这样一个命令就好了:

~/eos$ cleos push action eosio setpriv '["eosio.msig", 1]' -p eosio
executed transaction: fb64ed4c3a28eab846c350a83e05ac6ff836cc292ebe70716605246c22965078  192 bytes  39788 us
#         eosio <= eosio::setpriv               {"account":"eosio.msig","is_priv":1}
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

再次去执行提案,这次成功了:

~/eos$ cleos multisig exec eosio.msig nojack -p eosio.msig
executed transaction: 0cd43fe1de36ea35114bf1510132a8efc1d7a54809bb10ba60d96d3ec58527a7  336 bytes  526 us
#    eosio.msig <= eosio.msig::exec             {"proposer":"eosio.msig","proposal_name":"nojack","executer":"eosio.msig"}
warning: transaction executed locally, but may not be confirmed by the network yet    ] 

查询余额,看到已经转账成功:

~/eos$ cleos get currency balance acctoken jack
75.0000 EOS
~/eos$ cleos get currency balance acctoken bob
125.0000 EOS


 

猜你喜欢

转载自blog.csdn.net/liuzhijun301/article/details/84822375