1. 程式人生 > >EOS智慧合約之多重簽名

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 
[email protected]
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 [email protected]
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 [email protected], 1 [email protected], 
        active     1:    1 [email protected], 1 [email protected], 

部署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 [email protected]
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 [email protected]
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沒有許可權執行[email protected]許可,這是自然的。如果隨便部署一個合約都能執行別的賬戶的許可,這就是天大的安全問題。所以我們需要給這個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