公式ドキュメント だけでは実装につまづいたので、備忘録も兼ねて実装手順を記録しておきます。
この記事について
- EthFilterを生成し、トピックの追加によるイベントのフィルタリングを行えるようにする
環境
- Web3j 4.8.4
- Java 1.8
コントラクトとフィルタリングの想定
以下のコントラクトのイベントにおいて、 from
を特定のアドレスに絞りたい場合を考えます。
SampleContract.sol
contract SampleContract {
event StatusChange(
string status,
address indexed from
);
}
EthFilter の作成
以下の手順で EthFilter を作成します。
- EthFilter のインスタンスを作成
- イベント名と引数の型に関する情報を
addSingleTopic
を用いて追加 - フィルタリングしたいデータを
addOptionalTopics
を用いて追加
フィルタリングを行わない引数に対しては addOptionalTopics
の引数に nullを指定します。
Event event = new Event(
"SampleContract",
Arrays.asList(
new TypeReference<Utf8String>() {},
new TypeReference<Address>(true) {}
)
);
String topic = EventEncoder.encode(event);
System.out.println(Hash.sha3String("SampleContract(string,address)").equals(topic)); // => true
EthFilter filter = new EthFilter()
.addSingleTopic(topic)
.addOptionalTopics(
null,
new Address(256, fromAddress).toString() // Hex 256bit に正規化
);
web3j.ethLogFlowable(filter).subscribe(log -> {
...
});
コード生成機能を用いると、event を以下の形式で取得できます。
ContractName.EVENTNAME_MESSAGE
Event event = SampleContract.STATUSCHANGE_MESSAGE;
...