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里添加[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 alice@owner    

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

 

Inline action权限分析

    

   我们以【inline action开发实践】
<https://blog.csdn.net/itleaks/article/details/80535318>
博文中的实例为例,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权限机制】
<https://blog.csdn.net/itleaks/article/details/80422288>一文已经详细分析过了            
* 11中的check_authorization是检测[email protected]是否满足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)’已经具备[email protected]权限。然后authorization_manager只需检验to@active是否授权给[email protected]即可。通过这种虚拟的权限证明解决了合约调用合约的权限检测问题

    

 

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



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

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

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

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

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


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


友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信