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