【问链-EOS公开课】第十四课 EOS从单签名到多签名
一、基本知識(shí)
賬戶(hù):是存儲(chǔ)在區(qū)塊鏈上的人們可識(shí)別的ID。
權(quán)限:每個(gè)事務(wù)都有,它是由已配置許可的賬戶(hù)所評(píng)估的。
閾值:每個(gè)被命名的權(quán)限都有一個(gè)有效范圍,必須滿(mǎn)足是在許可下的一個(gè)簽名事務(wù),將被視為有效。
簽名:事務(wù)的簽名是通過(guò)利用一個(gè)客戶(hù)端來(lái)執(zhí)行,該客戶(hù)端擁有一個(gè)已加載并已解鎖的錢(qián)包。
錢(qián)包:可以保護(hù)及使用你的keys的一個(gè)軟件。這些keys可能是也可能不是區(qū)塊鏈?zhǔn)跈?quán)的一個(gè)許可賬戶(hù)。
錢(qián)包
錢(qián)包是一個(gè)客戶(hù)端,用于存儲(chǔ)keys,可能與也可能不與一個(gè)或多個(gè)賬戶(hù)進(jìn)行關(guān)聯(lián)。一個(gè)錢(qián)包會(huì)有鎖定和解鎖兩種狀態(tài),理想狀態(tài)下,它是被一個(gè)高熵密碼所保護(hù)。EOSIO有一個(gè)命令行客戶(hù)端cleos,與一個(gè)輕客戶(hù)端keosd交互,它倆構(gòu)成了eos錢(qián)包的這種模式。
賬戶(hù)
一個(gè)私人個(gè)體或者一個(gè)組織都可以擁有賬戶(hù),在交易或者其他push一個(gè)事務(wù)到區(qū)塊鏈上的時(shí)候,賬戶(hù)是必須的。
Authorities(權(quán)限) 和 Permissions(許可)
這兩個(gè)概念特別容易搞混為一談,這里給做一下區(qū)分。
Authorities決定了是否每一個(gè)給出的action都被正確授權(quán)。
每個(gè)賬戶(hù)都有兩個(gè)與生俱來(lái)的權(quán)限命名:
owner,象征著一個(gè)賬戶(hù)的所有權(quán)。只有很少的事務(wù)會(huì)需要這種權(quán)限。但最值得注意的是,actions可以對(duì)owner的權(quán)限做出各種改變。所以一般來(lái)說(shuō),建議owner被冷藏存儲(chǔ),不告訴任何人。owner可以用來(lái)回復(fù)另一個(gè)可能已遭泄露的許可。
active,用于轉(zhuǎn)移資金,投票生產(chǎn)者以及做其他高級(jí)賬戶(hù)的變更操作。唯一不同的是,它不能夠改變owner。
除了這兩個(gè)與生俱來(lái)的權(quán)限。一個(gè)賬戶(hù)也能擁有自定義命名的權(quán)限,它可以進(jìn)一步擴(kuò)展賬戶(hù)管理。自定義權(quán)限非常靈活并且提出了眾多可能的用例實(shí)現(xiàn)。在開(kāi)發(fā)者社區(qū),這些問(wèn)題已經(jīng)被提了出來(lái),包括他們是如何工作的,以及如果有的話是什么約定被采用了。許可對(duì)于任何給定的權(quán)限可以被分配到一個(gè)或多個(gè)公鑰或者一個(gè)有效的賬戶(hù)名稱(chēng)。
二、單簽名賬戶(hù)(默認(rèn)賬戶(hù)配置)
這里主要講述當(dāng)一個(gè)賬戶(hù)被創(chuàng)建以后,它是如何配置的。它分別擁有owner和active權(quán)限,可獨(dú)立設(shè)置key,兩個(gè)keys都是權(quán)重為1,且許可的閾值也都是1。該賬戶(hù)在執(zhí)行某個(gè)操作action時(shí),需要通過(guò)默認(rèn)的配置,單獨(dú)簽名授權(quán)一個(gè)本機(jī)權(quán)限。
創(chuàng)建賬戶(hù)
(在eos正式版本中,activeKey已不強(qiáng)制,變?yōu)榭蛇x)在創(chuàng)建賬戶(hù)時(shí),需要指定其owner和active兩個(gè)權(quán)限的key,這里要使用公鑰。所以,
cleos create account eosio alice EOS5JUBZXokmgHR7yHFgxoZdQZyfvu2oCHiPBeGUE3fQyZ9MHdmi8 返回結(jié)果如下: executed transaction: ac51aea40af91e283b7e99b431e36b4556bc8487d73c807118e30dd3324c4136 200 bytes 149 us # eosio <= eosio::newaccount {"creator":"eosio","name":"alice","owner":{"threshold":1,"keys":[{"key":"EOS5JUBZXokmgHR7yHFgxoZdQZy...這個(gè)版本只需要指定一個(gè)owner權(quán)限的key即可創(chuàng)建賬戶(hù)。active權(quán)限是小于owner的,所以顯得不那么重要。
三、多簽名賬戶(hù)
上面單簽名的內(nèi)容很簡(jiǎn)單,之所以介紹它,是為了與本節(jié)多簽名賬戶(hù)進(jìn)行比較學(xué)習(xí)。
多簽名賬戶(hù),一個(gè)賬戶(hù)假設(shè)為Jack的owner和active權(quán)限分別被授權(quán)為其他兩個(gè)賬戶(hù)Alice和Bob的許可。
@Jack
首先,我們創(chuàng)建至少三對(duì)key:
然后,分別使用不同的public key創(chuàng)建三個(gè)賬戶(hù):jack, alice和bob,創(chuàng)建成功以后,我們先來(lái)查看當(dāng)前jack賬戶(hù)的permission內(nèi)容:
cleos get account alice permissions: owner 1: 1 EOS5JUBZXokmgHR7yHFgxoZdQZyfvu2oCHiPBeGUE3fQyZ9MHdmi8active 1: 1 EOS5JUBZXokmgHR7yHFgxoZdQZyfvu2oCHiPBeGUE3fQyZ9MHdmi8 memory: quota: unlimited used: 2.66 KiB接著,按照上面我們?cè)O(shè)計(jì)的表格內(nèi)容,我們先對(duì)jack的owner權(quán)限進(jìn)行修改:
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: 494777ac55fa19144027ba5fdf75dcdaab4c4d52cdcaa13c0b6ecabfe622ffd1 160 bytes 136 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注意這里使用到了 cleos set account permission 命令。這條命令中比較重要的部分是第三個(gè)參數(shù)authority的內(nèi)容。
authority的內(nèi)容可以是:
- NULL,代表刪除權(quán)限
- public key,將該權(quán)限的內(nèi)容設(shè)置為一個(gè)公鑰
- JSON字符串,完整地復(fù)雜地設(shè)置一個(gè)賬戶(hù)某個(gè)權(quán)限的內(nèi)容
- 一個(gè)文件名,同上,只不過(guò)改為將完整配置放在文件中讀取
根據(jù)我們以上對(duì)jack owner權(quán)限的設(shè)計(jì)方案,是屬于比較復(fù)雜的權(quán)限內(nèi)容,因此這里采用的是第三種方式,及JSON字符串的方式。那么JSON字符串的格式是什么?我們例舉本次生效的配置格式化如下:
{"threshold": 2,"keys": [],"accounts": [{"permission": {"actor": "alice","permission": "owner"},"weight": 1},{"permission": {"actor": "bob","permission": "owner"},"weight": 1}],"waits": [] }我們分別來(lái)介紹這里面的字段:
threshold
目前最多只有兩個(gè)賬戶(hù),每個(gè)賬戶(hù)的權(quán)重都是1,所以threshold的取值范圍是1或者2。
1:在@Jack賬戶(hù)上執(zhí)行任何需要owner權(quán)限的操作必須由@Alice或者@Bob賬戶(hù)任意一個(gè)賬戶(hù)進(jìn)行簽名授權(quán)。
2:在@Jack賬戶(hù)上執(zhí)行任何需要owner權(quán)限的操作必須由@Alice和@Bob賬戶(hù)進(jìn)行多簽名授權(quán)。
keys
也可以通過(guò)JSON字符串設(shè)置秘鑰,這與在命令中第三個(gè)參數(shù)直接使用公鑰是相同的效果。但是要注意的是,如果該賬戶(hù)已經(jīng)通過(guò)JSON設(shè)置了復(fù)雜的權(quán)限內(nèi)容,再次修改的時(shí)候一定還需要使用原JSON數(shù)據(jù)進(jìn)行增量修改,若使用命令行加公鑰的方式會(huì)直接覆蓋掉原JSON設(shè)置的復(fù)雜權(quán)限內(nèi)容。
accounts
權(quán)限是通過(guò)其他賬戶(hù)來(lái)授權(quán),其中包括:
permission:某個(gè)賬戶(hù)actor的某個(gè)權(quán)限
weight,與上面的threshold呼應(yīng)使用
我們這里就是通過(guò)設(shè)置該字段來(lái)實(shí)現(xiàn)的多賬戶(hù)簽名。
waits
設(shè)置延時(shí)時(shí)間,最大不超過(guò)max_transacton_delay的配置值。
下面來(lái)設(shè)置其active權(quán)限,active權(quán)限與owner權(quán)限不同的是threshold的值,以及
賬戶(hù)除了owner權(quán)限是根權(quán)限以外,active本身是其子權(quán)限,而 cleos set account permission
命令設(shè)置的權(quán)限默認(rèn)都是active的子權(quán)限,注意,我們?cè)谠O(shè)置active權(quán)限本身的時(shí)候,要手動(dòng)指定其父權(quán)限為owner,否則會(huì)默認(rèn)指向自己,報(bào)錯(cuò)。
這樣,jack賬戶(hù)的權(quán)限就全部按照以上權(quán)限設(shè)計(jì)表格設(shè)置完畢了,下面我們使用命令來(lái)驗(yàn)證一下目前jack賬戶(hù)的權(quán)限內(nèi)容:
cleos get account jack permissions:owner 2: 1 alice@owner, 1 bob@owner,active 1: 1 alice@owner, 1 bob@owner四、多簽名過(guò)程實(shí)戰(zhàn)
1.部署eosio.msig合約
首先要注意的是,EOS中對(duì)多簽名的支持是通過(guò)eosio.msig智能合約來(lái)支持的,因此秉承eos"專(zhuān)人專(zhuān)責(zé)"的設(shè)計(jì)規(guī)范,我們先創(chuàng)建一個(gè)賬戶(hù)eosio.msig,并用該賬戶(hù)部署eosio.msig合約。
如果不是自己新增或者對(duì)原合約有修改的話,推薦直接使用build目錄下的contract,已經(jīng)生成好了相關(guān)的wast以及abi文件。
2.部署eosio.token合約
這里我們使用token合約的相關(guān)權(quán)限操作進(jìn)行多簽名的演示。同樣的,我們也創(chuàng)建一個(gè)賬戶(hù)eosio.token并用其部署eosio.token合約。
3.創(chuàng)建一個(gè)SYS token,并發(fā)放給jack,bob和alice三人分別100個(gè)。
cleos push action eosio.token create '["eosio","100000000.0000 SYS"]' -p eosio.token executed transaction: 260b8183e4d4e0d5c227971473791c8aecebf647856dd84c2eca8ae5365498df 120 bytes 257 us # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"100000000.0000 SYS"}轉(zhuǎn)賬之前先創(chuàng)建發(fā)行代幣用戶(hù)bank
cleos create account eosio bank EOS8fURVqUA6YHeKEHD6fLMvqj6NYEcFTqj6bNApCz24SVzFxKqev executed transaction: 8f98a0681cd1f2d787ef55583e93e7d7e250b4de7e24ea859de709e06be6b3ea 200 bytes 179 us # eosio <= eosio::newaccount "0000000000ea3055000000000000a73901000000010003f13ad86a535895877f448556649f9548631da55a1891a37f12e9e... cleos push action eosio.token issue '["bank","100000000.0000 SOS","issue token"]' -p eosio executed transaction: 8f04ae4a2bdd8442a8339f488c6cdf51175dabe9fc6e911c7c61dd8482390b31 128 bytes 810 us # eosio.token <= eosio.token::issue {"to":"bank","quantity":"100000000.0000 SYS","memo":"issue token"} # eosio.token <= eosio.token::transfer {"from":"eosio","to":"bank","quantity":"100000000.0000 SOS","memo":"issue token"} # eosio <= eosio.token::transfer {"from":"eosio","to":"bank","quantity":"100000000.0000 SOS","memo":"issue token"} # bank <= eosio.token::transfer {"from":"eosio","to":"bank","quantity":"100000000.0000 SOS","memo":"issue token"} cleos push action eosio.token transfer '["bank","jack","100.0000 SYS","transfer from bank to jack"]' -p bank cleos push action eosio.token transfer '["bank","alice","100.0000 SYS","transfer from bank to alice"]' -p bank cleos push action eosio.token transfer '["bank","bob","100.0000 SYS","transfer from bank to bob"]' -p bank4.然后我們調(diào)用命令,從jack轉(zhuǎn)50SYS給bob:
cleos push action eosio.token transfer '["jack","bob","50 SYS"]' -p jack@owner executed transaction: 8166f8503a098eeab6642afe375167e18bf79d0d904015f5bba19524ce2d56d6 144 bytes 846 us # eosio.token <= eosio.token::transfer {"from":"jack","to":"bob","quantity":"50 SYS","memo":""} # jack <= eosio.token::transfer {"from":"jack","to":"bob","quantity":"50 SYS","memo":""} # bob <= eosio.token::transfer {"from":"jack","to":"bob","quantity":"50 SYS","memo":""}5.查詢(xún)余額
cleos get currency balance eosio.token alice 100 SYS $ cleos get currency balance eosio.token jack 50 SYS $ cleos get currency balance eosio.token bob 150 SYS該命令執(zhí)行成功,是由jack@owner權(quán)限許可的該命令操作。到這里并沒(méi)有結(jié)束,jack的owner權(quán)限是與bob和alice相關(guān)的。所以可能遇到這么一個(gè)情況,jack今天不在,而它又需要以上的操作怎么辦?那么是否可以通過(guò)上面對(duì)jack權(quán)限的設(shè)置,在jack不在的情況下通過(guò)bob和alice的操作完成本屬于jack權(quán)限許可的操作呢?是的,這就是多簽名的概念和意義。
6. 建立多簽名操作提案
首先,eos中關(guān)于多簽名的命令是multisig,這也是通過(guò)第一步中eosio.msig合約實(shí)現(xiàn)的。
jack不在,要想通過(guò)bob和alice兩個(gè)人來(lái)審批本屬于jack的操作,這就要比jack本人操作要麻煩一點(diǎn),需要新建一個(gè)提案。
注意在提案中的定義操作要輸入完整的key-value對(duì)應(yīng)參數(shù)關(guān)系。本例中,transfer后面的參數(shù)的定義內(nèi)容與上面直接用jack是一致的,但格式是完整格式,上面jack單簽名時(shí)是使用的簡(jiǎn)略版,可自行對(duì)比發(fā)現(xiàn)。
這個(gè)提案結(jié)尾需要一個(gè)賬戶(hù)授權(quán),這個(gè)賬戶(hù)是不做限制的,只是為了日后操作這個(gè)提案本身,因此這里選擇一個(gè)不想關(guān)的用來(lái)部署eosio.msig合約的賬戶(hù)eosio.msig簽名授權(quán)該提案。
7. 查看提案
cleos multisig review eosio.msig nojack {"proposal_name": "nojack","packed_transaction": "38d0295b000000000000000000000100a6823403ea3055000000572d3ccdcd0100000000000091790000000080ab26a72e00000000000091790000000000000e3d320000000000000000535953000000000d74657374206d756c746973696700","transaction": {"expiration": "2018-06-20T03:55:36","ref_block_num": 0,"ref_block_prefix": 0,"max_net_usage_words": 0,"max_cpu_usage_ms": 0,"delay_sec": 0,"context_free_actions": [],"actions": [{"account": "eosio.token","name": "transfer","authorization": [{"actor": "jack","permission": "owner"}],"data": {"from": "jack","to": "bob","quantity": "50 SYS","memo": "test multisig"},"hex_data": "00000000000091790000000000000e3d320000000000000000535953000000000d74657374206d756c7469736967"}],"transaction_extensions": []} }重點(diǎn)查看該提案設(shè)定的action,包括該action需要的權(quán)限,操作名,參數(shù)等。
8.查看提案審批情況
multisig合約定義了兩個(gè)數(shù)據(jù)表,其中一個(gè)approvals表就是記錄了提案的審批狀態(tài)。
9.審批提案
提案創(chuàng)建完成以后,就需要alice和bob這兩個(gè)賬戶(hù)分別進(jìn)行審批,他們各自都需要使用自己的owner權(quán)限簽名審批這個(gè)動(dòng)作。
10.重新查看提案情況
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 }可以看到,原requested_approvals中的待審批項(xiàng)已經(jīng)全部轉(zhuǎn)到了provided_approvals 已審批列表中。
這里我們可以通過(guò)unapprove命令將已審批項(xiàng)轉(zhuǎn)至未審批集合中去。unapprove的參數(shù)與以上approve完全相同。
11.執(zhí)行提案
以上兩個(gè)非jack賬戶(hù)的審批過(guò)程就是多簽名的內(nèi)容,多簽名執(zhí)行成功以后,可以開(kāi)始執(zhí)行提案。
解決問(wèn)題:以上提案執(zhí)行過(guò)程會(huì)出現(xiàn)執(zhí)行失敗的情況,錯(cuò)誤信息:
{"auth":{"actor":"jack","permission":"owner"},"provided_delay":0,"provided_permissions":[{"actor":"eosio.msig","permission":"eosio.code"}],"provided_keys":[],"delay_max_limit_ms":388800000}解決方法是要部署system合約并利用system合約為多簽名合約的功能授權(quán),授權(quán)成功以后再執(zhí)行即可成功。
cleos push action eosio setpriv '["eosio.msig", 1]' -p eosio1個(gè)小坑:是在部署system合約時(shí)報(bào)錯(cuò)transaction took too long, 這種情況只需要在執(zhí)行命令時(shí)加 -x 參數(shù),默認(rèn)值是30s,改為60讓時(shí)間延長(zhǎng)一些即可執(zhí)行成功。
12. 驗(yàn)證結(jié)果
執(zhí)行成功以后,再次檢查各賬戶(hù)的SYS余額,能夠發(fā)現(xiàn)此提案的轉(zhuǎn)賬50個(gè)SYS的操作已經(jīng)生效。
五、自定義權(quán)限
上面提到了,除了owner和active權(quán)限之外,我們還可以自定義權(quán)限。仍在以上@Jack賬戶(hù)中進(jìn)行補(bǔ)充,增加一個(gè)自定義權(quán)限,名為publish:
weight:
權(quán)重,這是相對(duì)于上面threshold閾值的概念,就拿上面的屬于賬戶(hù)@Jack的publish權(quán)限來(lái)講,它包含三個(gè)子權(quán)限分別是:
@Alice賬戶(hù),權(quán)重為2
@Bob賬戶(hù),權(quán)重為2
一個(gè)keys,權(quán)重為1
而此時(shí)publish權(quán)限的閾值設(shè)定為2,也就是說(shuō),@Alice或@Bob任意一個(gè)賬戶(hù)均可以簽名授權(quán)@Jack賬戶(hù)的publish權(quán)限,因?yàn)檫@兩個(gè)賬戶(hù)的權(quán)重均為2,任意一個(gè)簽名都可保證夠到publish權(quán)限的閾值2。而如果只有權(quán)重為1的keys簽名,則必須再有以上任意一個(gè)賬戶(hù)來(lái)同時(shí)簽名,總權(quán)重達(dá)到了3,超過(guò)了publish閾值2才可以成功授權(quán)。
自定義權(quán)限部分的演示與上面的類(lèi)似,通過(guò)set account permission可以設(shè)置有key,有賬戶(hù),不同權(quán)重的十分復(fù)雜的權(quán)限內(nèi)容。這里不再贅述。
本文參考轉(zhuǎn)載來(lái)自【http://www.cnblogs.com/Evsward/p/msig.html?utm_source=debugrun&utm_medium=referral】
總結(jié)
以上是生活随笔為你收集整理的【问链-EOS公开课】第十四课 EOS从单签名到多签名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【问链-EOS公开课】第十三课 EOS插
- 下一篇: 【问链-链改进行时】 第二课 链改的技术