EOS智能合约开发系列(九): 高级权限设置

这是介绍EOS账户与权限的第二篇。上篇文章中,我们介绍了EOS的账户和权限这些概念,并介绍了一些权限设置的基本命令,包括如何自定义简单的权限。然而,EOS还有更为强大和灵活的权限自定义功能,还可以实现多重签名,本文就来介绍一下。

更灵活的自定义格式

还记得我们上篇文章中,自定义许可权限的命令吗?

cleos set account permission <account-name> <permission-name> <KEY> <parent-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@activecarl@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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容