这是介绍EOS账户与权限的第二篇。上篇文章中,我们介绍了EOS的账户和权限这些概念,并介绍了一些权限设置的基本命令,包括如何自定义简单的权限。然而,EOS还有更为强大和灵活的权限自定义功能,还可以实现多重签名,本文就来介绍一下。
更灵活的自定义格式
还记得我们上篇文章中,自定义许可权限的命令吗?
cleos set account permission -p accountname@active
这个命令中,我们使用的key,其实可以换成更多的东西,比如用一个JSON来描述的权限:
{
"threshold" : 100, /*An integer that defines cumulative signature weight required for authorization*/
"keys" : [], /*An array made up of individual permissions defined with an EOSIO-style PUBLIC KEY*/
"accounts" : [] /*An array made up of individual permissions defined with an EOSIO-style ACCOUNT*/
}
我们可以在其中指定多个keys
,并给予不同的权重,我们也可以指定多个accounts
,也同样可以设置不同的权重。注意threshold
的值可以是任意整数值,具体设多少,可以自己随意设置,只要满足自己的需求就行;怎么样知道是否满足需求呢?继续往下阅读,读懂了你就明白了。
使用多个keys授权的例子
cleos set account permission tester trans '{"threshold": 2, "keys":[
{"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight":2},
{"key":"EOS83sN8bfKGk3jTBezN41UN7LfXSVFa1w3YQcGApE67J26t3HLcr",
"weight":2}
]}' active -p tester@active
这里我们使用的授权JSON是:
{
"threshold": 2,
"keys": [{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 2
}, {
"key": "EOS83sN8bfKGk3jTBezN41UN7LfXSVFa1w3YQcGApE67J26t3HLcr",
"weight": 2
}]
}
意思是,如果我把这里设定的许可权限授予了两个人,那么他们中的任何一个都可以以trans
许可来签名交易。如果我们把trans
许可关联了transfer
action,那么也就意味这两个人中,任何一个人都可以进行转账交易。
如果你还没有把trans
许可与eosio.token
合约的 transfer
action 关联起来,可以这么做(在执行下面命令以前,需要打开tester的key所在的钱包,如果你是跟着本系列文章来的,那么tester的key在default
钱包里):
cleos set action permission tester eosio.token transfer trans
使用key固然挺好,但有一个缺点,就是太长了,太难记了。有没有更好的办法呢?有的,那就是用account,而且用account还有额外的好处。
使用多个账户名授权的例子
除了直接使用key以外,我们还可以使用多个账户名共同授权。使用账户名好处多,一方面,账户名要好记的多;另一方面,我们就不用关心key了,即便账户修改了active
或者owner
的许可,也对我们这个自定义的许可不会产生影响。
为了演示方便,以及为了后面演示多重签名的方便,我们先创建两个的钱包:bobwallet 和 carlwallet:
~ cleos wallet create -n bobwallet
Creating wallet: bobwallet
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5KKCuhViVgaP9MXLswpwDKPsXzcqfgeCuZHaHM8HuaUEV57fPHw"
~ cleos wallet create -n carlwallet
Creating wallet: carlwallet
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5KQyCcZp5QoMzp3kKSFkmizLe4mbG5vNBaG2VeD2815g2sp1DEG"
保存好钱包密码,我们创建两组key,并导入test钱包
~ cleos create key
Private key: 5KGnBSEAxmuhSJTLzsjTZie4hewMyToh4Mzq85pGDuzFRMQd9Yx
Public key: EOS8UTyktNUn4afScvYqMJ9JumGA27X7qmwgYpscwDoEHeFVYjDgb
~ cleos create key
Private key: 5KGhaQFuvPQjvKTR1VB1xpk8zUemgA2bXFL7hPVLx7PawNBUuKE
Public key: EOS7ufpQne6oXmanxvdoadmPkmfCT9rmtncML1tLRb7emgMrHgMBL
~ cleos wallet import --private-key 5KGnBSEAxmuhSJTLzsjTZie4hewMyToh4Mzq85pGDuzFRMQd9Yx -n carlwallet
imported private key for: EOS8UTyktNUn4afScvYqMJ9JumGA27X7qmwgYpscwDoEHeFVYjDgb
~ cleos wallet import --private-key 5KGhaQFuvPQjvKTR1VB1xpk8zUemgA2bXFL7hPVLx7PawNBUuKE -n bobwallet
imported private key for: EOS7ufpQne6oXmanxvdoadmPkmfCT9rmtncML1tLRb7emgMrHgMBL
如你所见,我们创建了两个key,一个导入了bobwallet
钱包,一个导入了carlwallet
钱包。
我们再创建两个账户bob和carl,他们分别拥有这两个key:
cleos create account user carl EOS8UTyktNUn4afScvYqMJ9JumGA27X7qmwgYpscwDoEHeFVYjDgb EOS8UTyktNUn4afScvYqMJ9JumGA27X7qmwgYpscwDoEHeFVYjDgb
cleos create account user bob EOS7ufpQne6oXmanxvdoadmPkmfCT9rmtncML1tLRb7emgMrHgMBL EOS7ufpQne6oXmanxvdoadmPkmfCT9rmtncML1tLRb7emgMrHgMBL
bob使用的是bobwallet钱包里的key,carl使用的是carlwallet钱包里的key。
我们这样做,是为了模拟这种情形:bob和carl这两个人有不同的钱包,并且他们都互相不知道对方的key。
现在我们考虑这么一个需求场景:tester用户拥有把自己账户的资金转出的权限。这不用说了,这是tester账户在被创建时就被赋予的权限;那么假如tester想把转账的权利赋予bob和carl呢?仅仅是转账的权力,其他的权力他想保留。那么它该怎么办呢?
你应该想到了本文开始时的例子了,我们当时用的key,很类似,对吧?我们现在可以直接用账户名了,可以这么做:
cleos set account permission tester trans '{"threshold": 2, "accounts":[
{
"permission":
{"actor":"bob","permission":"active"},
"weight":2
},
{"permission":
{"actor":"carl","permission":"owner"},
"weight":2}
]}' active -p tester@active
执行完成之后,我们看一下tester的账户情况:
~ cleos get account tester
permissions:
owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
active 1: 1 EOS83sN8bfKGk3jTBezN41UN7LfXSVFa1w3YQcGApE67J26t3HLcr
trans 2: 2 bob@active, 2 carl@owner,
vote 4: 3 EOS7LVbDSU3hMewm8F2sxXUNDFPCUmqNvpYJe4TCg58GJ9UW8bo3M, 1 EOS83sN8bfKGk3jTBezN41UN7LfXSVFa1w3YQcGApE67J26t3HLcr
可以看到trans
许可的阀值(threshold)是2, bob@active
和carl@owner
这两个权限的权重也都是2,也就是说,他们中的任何一个都可以让执行trans
权限,我们前面给trans
关联的是eosio.token
合约的transfer
action,也就是说,bob和carl任何一个人都可以签名转账交易。刚好满足了tester想下放转账权限的需求。
我们来验证一下,我们先把所有的钱包都锁住。然后只解锁bobwallet,然后用bob@active
对tester账户进行转账,可参考上一篇内容:
~ cleos wallet lock_all
Locked All Wallets
~ cleos wallet unlock -n bobwallet
password: Unlocked: bobwallet
~ cleos push action eosio.token transfer \
'[ "tester", "user", "0.5000 SYS", "2 you know how much i love you" ]' -p tester@trans
executed transaction: 052dd5ee257b1760a48e906e8fe1b345cbcc6b1dbadcd1c29cf85936c252f220 160 bytes 7942 us
# eosio.token <= eosio.token::transfer {"from":"tester","to":"user","quantity":"0.5000 SYS","memo":"2 you know how much i love you"}
# tester <= eosio.token::transfer {"from":"tester","to":"user","quantity":"0.5000 SYS","memo":"2 you know how much i love you"}
# user <= eosio.token::transfer {"from":"tester","to":"user","quantity":"0.5000 SYS","memo":"2 you know how much i love you"}
如你所见,成功了。你可以试试把所有的钱包都关闭,然后打开carlwallet,然后再执行上面的转账操作,你会发现也是成功的。
不知道你有没有发现,这个转账命令,其实无需指定你用那个钱包或者用哪个key签名,cleos
自动从已经解锁的钱包里找出符合条件的key对交易进行签名,所以我们只需要打开拥有相应key的钱包就可以了。
你可能会说,感觉这个东西太复杂,用处也不是很大,不就是可以把账户的某些操作放权嘛。其实,这里的放权,只是其中一个功能;我想你应该也想到了一些,比如,如果我把每个用户的权重改的小一些,小于threshold,会怎么样?
你能想到这一点,说明你很聪明,这就是多重签名了,我们后面继续讲解。
简介:不羁,一名程序员;专研EOS技术,玩转EOS智能合约开发。
微信公众号:know_it_well
知识星球地址:https://t.zsxq.com/QvbuzFM