EOS 学習メモ:EOSIO_DISPATCH 編

in #eos6 years ago (edited)

EOS 学習メモ:別 contract に対する inline action 編 の続き。

今回は、これまで呪文の如く contract 最下部に記載し続けてきた EOSIO_DISPATCH について。

EOSIO_DISPATCH について考える前に、まずは apply action handler について。この apply action handler は dispatcher とも呼ばれ、その名の通り、全ての action を待ち受け、action が発生したら、それと対応した目的の処理を実行する。具体的には、receiver(処理実行中の account)と code(呼び出し元の account)と action を引数とし、action とそれと対応する実装した action handler のマッピングを行っている。なお、全ての contract はこれを実装する必要がある。

が、これまで実装してきた contract には apply action handler を明示的には実装していない。どういうことだろうか?

そう、EOSIO_DISPATCH は上記のマッピングを自動生成するための macro なのである。この macro のおかげで、EOSIO_DISPATCH(addressbook, (upsert)(erase)(notify)) などと書くだけで、必要なマッピングを行う apply action handler が自動的に実装されていた、ということ。

実際の EOSIO_DISPATCH の中身 は以下のようになっている。

 #define EOSIO_DISPATCH( TYPE, MEMBERS ) \
 extern "C" { \
    void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
       if( code == receiver ) { \
          switch( action ) { \
             EOSIO_DISPATCH_HELPER( TYPE, MEMBERS ) \
          } \
          /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
       } \
    } \
 } \



codereceiver でない場合はスキップするようになっている。すなわち、呼び出し元の account が処理実行中の account でない場合は action に対応する action handler は呼び出されない。

また、inline action として別 contract から実行された場合の code は処理実行中の account と同じだが、require_recipient() で実行された場合の code は呼び出し元の別 account になるので注意。

今回はここまで。