EOS 学習メモ:custom dispatcher 編 ③steemCreated with Sketch.

in #eos6 years ago (edited)

dg1uxga7sv.jpg

EOS 学習メモ:custom dispatcher 編 ② の続き。

今回実装した contract は こんな感じ。dispatcher は最低限のルーティングをするだけで、前回までは dispatcher が担っていた receivercode のチェック処理含めて action handler にぶん投げている。もちろん、全部ぶん投げることが必須ではないので、良く言えば「dispatcher 内でも action handler 内でも receivercode を参照した処理制御が可能」という点で、非常に柔軟な custom dispatcher(というか contract)の実装パターンと言える。

dispatcher だけ抜き出すと以下のようになる。

 extern "C" {
   void apply(uint64_t receiver, uint64_t code, uint64_t action) {
     switch (action) {
     case name("a").value: return a(receiver, code);
     case name("b").value: return b(receiver, code);
     case name("c").value: return c(receiver, code);
     }
   }
 };



action handler が receivercode を内容をチェックするには、当然 action handler に receivercode を渡してあげる必要があるので、前回まで使っていた execute_action() は使えない。よって、上記のようになっている。また、action handler が receivercode を受け取るためには、そもそも action handler からごそっと実装し直さないといけない。

実装し直した action handler を 1 つ抜き出すと以下のようになる。

 struct in {
   name user;
   EOSLIB_SERIALIZE(in, (user))
 };

 void a(uint64_t self, uint64_t code) {
   eosio_assert(code == self, "assertion failed in a");
   auto data = unpack_action_data<in>();
   require_auth(data.user);
   print("Hi, ", data.user, " from a");
 }



今までは dispatcher 内で行っていたチェック処理を action dispatcher 内で行い、unpack_action_data() によって action request を unpack して引数を取り出してから、前回までと同様の処理を行っている。

こんな感じで、コードはほとんど書き直すことになる。そして、この書き直しによって eosio-cpp の ABI generator では ABI を生成できなくなる。これが柔軟性の代償。ということで、今回は contract に合わせて以下のような ABI を手書きする。

 {
     "____comment": "This file was generated with eosio-abigen. DO NOT EDIT Thu Feb 14 12:17:31 2019",
     "version": "eosio::abi/1.1",
     "structs": [
         {
             "name": "in",
             "base": "",
             "fields": [
                 {
                     "name": "user",
                     "type": "name"
                 }
             ]
         }
     ],
     "types": [],
     "actions": [
         {
             "name": "a",
             "type": "in",
             "ricardian_contract": ""
         },
         {
             "name": "b",
             "type": "in",
             "ricardian_contract": ""
         },
         {
             "name": "c",
             "type": "in",
             "ricardian_contract": ""
         }
     ],
     "tables": [],
     "ricardian_clauses": [],
     "variants": [],
     "abi_extensions": []
 }



基本的な ABI の書き方は EOS 学習メモ:ABI 編 を参照。

今回ここまで。

Sort:  

Thanks for using eSteem!
Your post has been voted as a part of eSteem encouragement program. Keep up the good work! Install Android, iOS Mobile app or Windows, Mac, Linux Surfer app, if you haven't already!
Learn more: https://esteem.app
Join our discord: https://discord.gg/8eHupPq