イーサリアムのコントラクトのイベントについて、よく理解できてないので、調べてみました。
説明
- イベントは、コントラクト上で発生したことをDAPPなどのクライアントに通知することができる
- イベントが呼び出されると、実際渡された関数のパラメータをトランザクションのログに保持し、コントラクトのアドレスと関連を付けられる。
- トランザクションがブロックに保持されるので、イベントも同じく、ブロックが存在している限り、イベントのログもずっと存在している
- ただ、ログとイベントは、コントラクトから(コントラクトの作成者でも)直接にアクセスできない
- イベントのパラメータは
indexed
で定義できる。indexed
付けると、そのパラメータまたは特定の値に従ってフィルターできる- 配列の場合は、
Keccak-256
のハッシュ値で保持される -
indexed
ついてないパラメータはログの一部として保持される
- 配列の場合は、
使ってみる
pragma solidity ^0.4.17;
contract MyToken {
event Deposit(
address indexed _from,
bytes32 indexed _id
);
function deposit(bytes32 _id) public {
// deposit pproc
// log
Deposit(msg.sender, _id);
}
}
- Ganache起動してから、 Remix を
127.0.0.1:7545
に接続しておく - 上記内容を Remix に貼り付けて、デプロイする
- 上記内容ですと、
deposit
関数を呼び出すと、添付画像のように、トランザクションのlogs
項目に、ちゃんとイベント名とパラメータが保持されている
![スクリーンショット 2017-12-22 23.37.41.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F4777%2F0e1ba8c1-6713-1081-2f9c-7c305aa2bbdc.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=27da55c4558538dda735ecd6be016860)
-
Deposit(msg.sender, _id);
をコメントアウトして、コントラクトを再度デプロイし、deposit
関数を呼び出すと、下記のように、logs
項目が空になる
![スクリーンショット 2017-12-22 23.37.53.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F4777%2F2abc04e2-23e6-e609-98c2-b83255727ea8.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=11a206e41f35992007bc9e58be0db8d2)
まとめ
- コントラクトの処理で、ちゃんとログを残したい場合は、イベントを活用しましょう。