美文网首页
EOS智能合约开发系列(九): 高级权限设置

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

作者: 鹏飞_3870 | 来源:发表于2018-08-21 21:39 被阅读0次

    这是介绍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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/zvsjiftx.html