[EOS源码分析]8.EOS保留权限eosio.code深度解读

59 篇文章 0 订阅
12 篇文章 25 订阅

    inline action简单来说就是action调用另外一个action, 具体来说就是一个智能合约的代码调用另外一个智能合约的函数。

   eoiso.code这一特殊权限是dawn4.0后新增的内部特殊权限,用来加强inline action的安全性。比如alice调用智能合约contract1.test,一开始alice看过contract1.test的逻辑,发现它只是一个打印函数,并不会调用其他合约。所以alice以自己active的权限alice@active去执行contract1.test。但是contract1的拥有者某一天可能偷偷更改了test的实现,在test函数中调用eosio.token的transfer函数以alice@active权限就可以取走alice的EOS. 为了解决权限乱用问题,EOS新增了eosio.code这个特殊权限。采用eosio.code后,contract1.test要以alice@active去调用eosio.token,必须得到alice的授权,即必须在alice@active里添加contrac1@eosio.code授权

$cleos set account permission alice active '{"threshold": 1,"keys": [{"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", "weight":1}],"accounts": [{"permission":{"actor":"contract1","permission":"eosio.code"},"weight":1}]}' owner -p alice@owner    

    即用户调用push action -p permission授权的权限只作用域该action,要用到其他action必须再授权eosio.code

 

Inline action权限分析

    

   我们以【inline action开发实践】博文中的实例为例,hello.code智能合约调用hello.target合约

 

class hello : public eosio::contract {

  public:

    using contract::contract;

    /// @abi action 

    void hi( account_name from, account_name to) {

        require_auth(from);

        print( "Hello, from:", name{from}, ", to:", name{to});

        action(

            //这里{to, active}必须授权给{_self, eosio.code}

            permission_level{to, N(active)},

            //调用 hello.target合约 的'callme' action

            N(hello.target), N(callme),

            std::make_tuple(to)

         ).send();

    }

};

       

 通过下面的命令执行hello.code智能合约 

$cleos push action hello.code hi '["args.user","args.user1"]' -p args.user

    

    调用时序图如下

    

   时序图中有2次调用check_authorization

  • 3中的check_authorization是检测交易的签名是否满足action 'hello.code@hi'调用的权限声明args.user@active,这个检测机制已经在【EOS权限机制】一文已经详细分析过了            
  • 11中的check_authorization是检测hello.code@eosio.code是否满足action "hello.target@callme"的权限声明to@active(这里的to='args.user1'),也就是args.user1@active。所以为了让这个inline action调用成功,必须添加如下授权

$cleos set account permission args.user1 active '{"threshold": 1,"keys": [],"accounts": [{"permission":{"actor":"hello.code","permission":"eosio.code"},"weight":1}]}' owner -p args.user1@owner

     这里有个疑问,为啥是检测(hello.code, eosio.code)授权是否满足权限声明呢?我们仔细看下上面的hi代码

   void hi( account_name from, account_name to) {

        require_auth(from);

        print( "Hello, from:", name{from}, ", to:", name{to});

        action(

            //这里{to, active}必须授权给{_self, eosio.code}

            permission_level{to, N(active)},

            //调用 hello.target合约 的'callme' action

            N(hello.target), N(callme),

            std::make_tuple(to)

         ).send();

    }

    当hello.code智能合约代码通过action.send调用其他智能合约时,hi代码是拿不到任何私钥的,也就没法为声明的权限签名,即没法证明该智能合约具备action声明的权限to@active。因此,只有系统代码做担保了,因而系统提出了一个虚拟权限eosio.code。然后系统直接告诉系统检验逻辑(authorization_manager) ,‘action(hello.target)’已经具备hello.code@eosio.code权限。然后authorization_manager只需检验to@active是否授权给hello.code@eosio.code即可。通过这种虚拟的权限证明解决了合约调用合约的权限检测问题

    

 

    上面红色的部分就是系统代为担保的权限证明。对于用户直接提交的action,这个权限证明是从transaction的签名里恢复出来的

/********************************

* 本文来自CSDN博主"爱踢门"

* 转载请标明出处:http://blog.csdn.net/itleaks

******************************************/

如果你对EOS,ETH技术及开发感兴趣,请入QQ群讨论: 829789117


如需实时查看最新文章,请关注公众号"区块链斜杠青年",一起探索区块链未来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值