今回は以下をやってみる。
- action の実行を別の account に通知する
- ある action の中で別の action を実行する
まず、前者については require_recipient()
を利用する。引数に account を渡すことで、その account に対して実行中の action が通知される。今回は通知専用の notify
action handler を実装し、この中で require_recipient()
を実行する。が、これを public にして置いておくと誰でも実行できるようになってしまうため、嘘の通知が飛ばせてしまう。そこで、require_recipient()
を実行する前に require_auth(get_self())
を実行し、addressbook
contract がデプロイされている account からの内部的な呼び出し以外は弾くようにする。
後者については、action()
を send()
することで実現する。action()
の引数には、使用する権限、実行対象の action を特定するための情報、action に渡す引数などを指定する。今回は notify
action を inline action として実行する処理を共通化するために send_summary()
という private method として実装する。
ということで、修正した addressbook
contract をいつも通りコンテナ上に持っていく。
$ docker cp contracts/addressbook-with-inline-action/addressbook.cpp eos:/tmp/contracts/addressbook/addressbook.cpp
コンテナに接続。
$ docker exec -it eos bash
以降、コンテナ上で作業を進める。
修正した addressbook.cpp
をコンパイルする。
$ cd /tmp/contracts/addressbook
$ eosio-cpp -o addressbook.wasm addressbook.cpp --abigen
addressbook
account に対してデプロイする。
$ cleos set contract addressbook . -p addressbook@active
Reading WASM from /tmp/contracts/addressbook/addressbook.wasm...
Publishing contract...
executed transaction: 6aca8997b7fad18110c1a722cc78fe482c131e28095d7f4ab965c10750155de9 7808 bytes 4123 us
# eosio <= eosio::setcode {"account":"addressbook","vmtype":0,"vmversion":0,"code":"0061736d0100000001b6011c60037f7e7f0060027f...
# eosio <= eosio::setabi {"account":"addressbook","abi":"0e656f73696f3a3a6162692f312e31000405657261736500010475736572046e616d...
upsert
action を実行して、9 歳だった alice
を 21 歳にする。このとき、upsert
action handler の中で send_summary()
が実行され、send_summary()
が notify
action を inline action として実行する。notify
action handler の中で require_recipient()
が実行され、notify
action の実行が alice
に通知される。
$ cleos push action addressbook upsert '["alice", "alice", "liddell", 21, "123 drink me way", "wonderland", "amsterdam"]' -p alice@active
executed transaction: f26cf2283af460ba97c3527ded14ad8e7f1d074f67de412f57e3a7531877edc2 160 bytes 17300 us
# addressbook <= addressbook::upsert {"user":"alice","first_name":"alice","last_name":"liddell","age":21,"street":"123 drink me way","cit...
# addressbook <= addressbook::notify {"user":"alice","msg":"alice successfully modified record to addressbook"}
# alice <= addressbook::notify {"user":"alice","msg":"alice successfully modified record to addressbook"}
最終行のログを見ると、alice
に対して通知がいっているような様子が見てとれる。
実際に alice
に関連する action のログを取得してみる。
$ cleos get actions alice
# seq when contract::action => receiver trx id... args
================================================================================================================
...
# 19 2019-02-04T13:50:59.000 addressbook::notify => alice f26cf228... {"user":"alice","msg":"alice successfully modified record to...
無事、inline action を介した通知が alice
に届いた模様。
今回はここまで。
✅ Enjoy the vote! For more amazing content, please follow @themadcurator for a chance to receive more free votes!