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

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

 

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

    

    即用户调用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

    

    调用时序图如下

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

   时序图中有2次调用check_authorization

3中的check_authorization是检测交易的签名是否满足action '[email protected]'调用的权限声明[email protected],这个检测机制已经在【EOS权限机制】一文已经详细分析过了            
11中的check_authorization是检测[email protected]是否满足action "[email protected]"的权限声明[email protected](这里的to='args.user1'),也就是[email protected]。所以为了让这个inline action调用成功,必须添加如下授权
$cleos set account permission args.user1 active '{"threshold": 1,"keys": [],"accounts": [{"permission":{"actor":"hello.code","permission":"eosio.code"},"weight":1}]}' owner -p [email protected]

     这里有个疑问,为啥是检测(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声明的权限[email protected]。因此,只有系统代码做担保了,因而系统提出了一个虚拟权限eosio.code。然后系统直接告诉系统检验逻辑(authorization_manager) ,‘action(hello.target)’已经具备[email protected]权限。然后authorization_manager只需检验[email protected]是否授权给[email protected]即可。通过这种虚拟的权限证明解决了合约调用合约的权限检测问题

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

 

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

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

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

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

* 转载请标明出处:http://blog.csdn.net/itleaks
--------------------- 
作者:ITleaks 
来源:CSDN 
原文:https://blog.csdn.net/itleaks/article/details/80557560 
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章:

  • 2021-09-12
  • 2021-05-04
  • 2021-04-09
  • 2021-08-07
  • 2021-11-19
  • 2022-01-13
  • 2021-11-18
  • 2021-11-28
猜你喜欢
  • 2021-12-20
  • 2021-10-16
  • 2021-07-27
  • 2021-06-14
  • 2021-12-09
  • 2021-05-04
  • 2022-12-23
相关资源
相似解决方案