LoginSignup
3
1

More than 5 years have passed since last update.

[Web3.js]発火したイベントをフィルターかけて取得する方法

Posted at

簡単ですが、ちょっとだけ実装に手間取ったのでメモがわりに残しておきます。

環境
Solidity version: 0.5.0
Truffle version: 5.0.1
Web3.js version: 1.0.0

SolidityはEventというフロントエンドでコントラクトを監視する機能がついてます。
つまりブロックチェーン上(Solidity, コントラクト)で何か起きたらフロントエンド(ブラウザ)でそれを察知するという形です。
さらにindexedというmodifierを使うことで、フィルタリングしてある条件の時だけイベントを取得する様にできます。

とりあえずコード書いていきます。

Sample.sol
contract Sample{
   uint testData;
   event SetData(address indexed from, uint indexed data);

   function set(uint _data) public {
       data = _data
       emit SetData(msg.sender, data);
   }
}

後々フィルターをかけたい条件にはindexedというmodifierをつけてください。これをつけないと、フィルタリングできません。

sample.js
    var sampleInstance = instance_set // sampleInstance: コントラクトのインスタンス
    var account = account_set // account: 今ログインしているアカウント

    var dataSetEvent = sampleInstance.Sample({from: account},{fromBlock:1, toBlock: "latest"});

    dataSetEvent.watch((error, result) => {
                  console.log(result);
              });

まずはイベントが登録されてるコントラクトのインスタンスを取得します。instance_setはテキトーに入れた変数なので、App.contracts.Sample.deployed().then()みたいな形でインスタンスを取得してください。同様にaccount_setとテキトーに書きましたが正しい手段で現在のアカウントを取得します。この辺は本筋から離れるので省略して書きました。すみません。

sampleInstanceというコントラクトのインスタンスからSampleイベントを呼び出します。そして第一引数に検索条件、第二引数に検索するブロック範囲を入力します。今回は1番目のブロックから最新のブロックで条件入力してますが、適宜必要なブロック範囲を入力してください。ブロック範囲に関しては入力しないと正しい値が返ってきませんでした。

第一引数は入力しなくても値は返ってきます。上記のコードでfrom: accountを入力せずに空白にするとブロック番号1から最新のブロックまでで発火したSampleイベント全てが返ってきます。

取得したdataSetEventを監視するために.watchメソッドを使います。
resultにはイベントに関するログが入っていて、その一部には引数であるfromやdataが入っています。

こんな感じです。何か間違っていたらコメント頂けると幸いです。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1