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); */ \
} \
} \
} \
code
が receiver
でない場合はスキップするようになっている。すなわち、呼び出し元の account が処理実行中の account でない場合は action に対応する action handler は呼び出されない。
また、inline action として別 contract から実行された場合の code
は処理実行中の account と同じだが、require_recipient()
で実行された場合の code
は呼び出し元の別 account になるので注意。
今回はここまで。