EOS 学習メモ:別 contract に対する inline action 編

m0t0k1ch1(48)
Published in
#eos
Words
445
Reading
2 min
Listen
Play
8y

software-3682509_1920.jpg

EOS 学習メモ:通知と inline action 編 の続き。

注:この記事に記載してある検証を行う前に、ローカルのコンテナ上で 2 週間ほど起動し続けた nodeos がデフォルトの DB 容量上限に達してしまったらしく、動かなくなってしまった。上限の設定を変えれば問題なさそうだが、今回は復習も兼ねて一度全てのデータ(/tmp/contracts/eosio)を削除して新しいチェーンを立ち上げてから以下の検証を行なった。

前回は同 contract 内の action を inline action として実行したが、今回は別 contract の action を inline action として実行してみる。

ということで、addressbook contract とは別で、addressbook contract における各データの登録・更新・削除の回数をカウントする abcounter contract を実装した。また、addressbook contract にも修正を加え、abcounter countract の action を実行するようにする。修正後の addressbook contract は コチラ

abcounter contract と、修正した addressbook contract をコンテナ上に持っていく。

 $ docker cp contracts/abcounter eos:/tmp/contracts
 $ docker cp contracts/addressbook-with-counter/addressbook.cpp eos:/tmp/contracts/addressbook/addressbook.cpp



コンテナに接続。

 $ docker exec -it eos bash



以降、コンテナ上で作業を進める。

まず、abcounter contract をデプロイするために abcounter account をつくる。

 $ cleos create account eosio abcounter EOS74MfAgXfFQX36paLQp5tuApRPoHxn4JCcBiwTFWorF5Cj1qMK7 -p eosio@active
 executed transaction: 33adb4234ca8e7a44c387e978c114c7b847a205ae73d4d33882990501bc811fb  200 bytes  42382 us
 #         eosio <= eosio::newaccount            {"creator":"eosio","name":"abcounter","owner":{"threshold":1,"keys":[{"key":"EOS74MfAgXfFQX36paLQp5t...



abcounter.cpp をコンパイルする。

 $ cd /tmp/contracts/abcounter
 $ eosio-cpp -o abcounter.wasm abcounter.cpp --abigen



abcounter contract を abcouter account に対してデプロイする。

 $ cleos set contract abcounter . -p abcounter@active
 Reading WASM from /tmp/contracts/abcounter/abcounter.wasm...
 Publishing contract...
 executed transaction: 89404ecdd270b0468d9527d4557eda18a050bdec697fe38ff1c2c4764a4331c9  4920 bytes  122894 us
 #         eosio <= eosio::setcode               {"account":"abcounter","vmtype":0,"vmversion":0,"code":"0061736d010000000192011860037f7e7f0060000060...
 #         eosio <= eosio::setabi                {"account":"abcounter","abi":"0e656f73696f3a3a6162692f312e31000205636f756e7400020475736572046e616d65...



これで abcounter contract 側の準備は完了。

次は、修正した addressbook contract をコンパイルする。

 $ 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: 44beb96dc7d58a440ca140145b5a5dcc6e263ee4b0e2ff4b94c167efdd6bd9bc  8080 bytes  28229 us
 #         eosio <= eosio::setcode               {"account":"addressbook","vmtype":0,"vmversion":0,"code":"0061736d0100000001b6011c60037f7e7f0060027f...
 #         eosio <= eosio::setabi                {"account":"addressbook","abi":"0e656f73696f3a3a6162692f312e31000405657261736500010475736572046e616d...



addressbook contract が別 contract の action を実行できるようにするためには addressbook account の active permission に eosio.code を追加する必要があるらしいので、する。なお、こうなっているのは、セキュリティ上の理由かららしい。意図しない外部 contract の action 実行を防ぐためってことだろうか。

 $ cleos set account permission addressbook active --add-code
 executed transaction: 230906c0038cee132392179fcc123926689b350070ae5c7f1487f3bef83e6b4c  184 bytes  17338 us
 #         eosio <= eosio::updateauth            {"account":"addressbook","permission":"active","parent":"owner","auth":{"threshold":1,"keys":[{"key"...



どうなったのか確認してみる。

 $ cleos get account addressbook
 created: 2019-02-06T14:14:16.000
 permissions:
      owner     1:    1 EOS74MfAgXfFQX36paLQp5tuApRPoHxn4JCcBiwTFWorF5Cj1qMK7
         active     1:    1 EOS74MfAgXfFQX36paLQp5tuApRPoHxn4JCcBiwTFWorF5Cj1qMK7, 1 addressbook@eosio.code
 memory:
      quota:       unlimited  used:     185.5 KiB

 net bandwidth:
      used:               unlimited
      available:          unlimited
      limit:              unlimited

 cpu bandwidth:
      used:               unlimited
      available:          unlimited
      limit:              unlimited



確かに、active permission に [email protected] が追加されている模様。



さて。ここまでで準備は整ったので、alice のデータを addressbook contract に登録してみる。今回の alice は 19 歳。

 $ cleos push action addressbook upsert '["alice", "alice", "liddell", 19, "123 drink me way", "wonderland", "amsterdam"]' -p alice@active
 executed transaction: 6c91d5f3e5bf6508bf4c105125201382de92110fa477a699b1e517c3058c0a38  160 bytes  20758 us
 #   addressbook <= addressbook::upsert          {"user":"alice","first_name":"alice","last_name":"liddell","age":19,"street":"123 drink me way","cit...
 #   addressbook <= addressbook::notify          {"user":"alice","msg":"alice successfully emplaced record to addressbook"}
 #         alice <= addressbook::notify          {"user":"alice","msg":"alice successfully emplaced record to addressbook"}
 #     abcounter <= abcounter::count             {"user":"alice","type":"emplace"}



abcounter contract できちんとカウントされているか確認する。

 $ cleos get table abcounter abcounter counts --lower alice --limit 1
 {
   "rows": [{
       "key": "alice",
       "emplaced": 1,
       "modified": 0,
       "erased": 0
     }
   ],
   "more": false
 }



冒頭で記載した通り、チェーンは初期化しているので、先ほどの upsert は新規登録に相当する。よって、"emplaced" が 1 になっている上記の状態で正解。問題なさそう。

次はデータ更新。

 $ cleos push action addressbook upsert '["alice", "alice", "liddell", 21, "1 there we go", "wonderland", "amsterdam"]' -p alice@active
 executed transaction: 5f128c39a4d0121b7c3af1b5674e55e4714b12d389db3d5958dade1f03f5e346  160 bytes  26850 us
 #   addressbook <= addressbook::upsert          {"user":"alice","first_name":"alice","last_name":"liddell","age":21,"street":"1 there we go","city":...
 #   addressbook <= addressbook::notify          {"user":"alice","msg":"alice successfully modified record to addressbook"}
 #         alice <= addressbook::notify          {"user":"alice","msg":"alice successfully modified record to addressbook"}
 #     abcounter <= abcounter::count             {"user":"alice","type":"modify"}



abcounter contract を確認する。

 $ cleos get table abcounter abcounter counts --lower alice --limit 1
 {
   "rows": [{
       "key": "alice",
       "emplaced": 1,
       "modified": 1,
       "erased": 0
     }
   ],
   "more": false
 }



"modified" が 0 から 1 に増えている。想定通りの挙動。

次はデータ削除。

 $ cleos push action addressbook erase '["alice"]' -p alice@active
 executed transaction: 2551649d56149a98a65c27c753d9d2435cc8170e3b3ccab9b7afc7280289d0ad  104 bytes  26379 us
 #   addressbook <= addressbook::erase           {"user":"alice"}
 #   addressbook <= addressbook::notify          {"user":"alice","msg":"alice successfully erased record from addressbook"}
 #         alice <= addressbook::notify          {"user":"alice","msg":"alice successfully erased record from addressbook"}
 #     abcounter <= abcounter::count             {"user":"alice","type":"erase"}



abcounter contract を確認する。

 $ cleos get table abcounter abcounter counts --lower alice --limit 1
 {
   "rows": [{
       "key": "alice",
       "emplaced": 1,
       "modified": 1,
       "erased": 1
     }
   ],
   "more": false
 }



"erased" が 0 から 1 に増えている。想定通りの挙動。

以上より、addressbook contract におけるデータの登録・更新・削除の 3 つの処理が全て inline action として abcounter contract という別 contract の count action を実行し、それぞれの処理回数をカウントできていることが確認できた。もちろん、複数回実行すれば、1 → 2 → ... とどんどんカウントされていく。

今回はここまで。