Hyperledger FireFlyとイベント管理

前回までには、NFTトークンの扱いについて説明しました。
今回はFireflyのイベント管理機能について紹介します。
## イベント駆動型プログラミングモデル
Fireflyは、非常に優れたプログラムの一つです。その中でも、最も重要な概念は「イベント駆動型プログラミングモデル」です。簡単に説明すると、Fireflyでは参加者がメッセージやトランザクション（データのやり取りのようなもの）を相互に送り合います。これらのメッセージやトランザクションは、ブロックチェーン内外で送受信できます。そして、これらのイベントが集約され、確認されると、他の参加者に何らかの処理をトリガーします。この仕組みにより、多数の参加者が関与する複雑なシステムやビジネスプロセスを調整することが可能になります。Fireflyは各参加者に、彼ら自身のプライベートヒストリーを提供します。このヒストリーには、ブロックチェーンをバックエンドとするトランザクションだけでなく、完全にオフチェーンのメッセージのやり取りも含まれています。
今回の説明では、WebSockクライアントを使用します。
※ 「https://hyperledger.github.io/firefly/tutorials/events.html Listen for events」より引用
## 前提
* swagger UIの利用
* スマートコントラクトEVMイベントの基礎知識
* chrome拡張機能にBrowser WebSocket Clientがインストール済（[Browser WebSocket Client](https://chrome.google.com/webstore/detail/browser-websocket-client/mdmlhchldhfnfnkfmljgeinlffmdgkjo)）
:::note info
EVMのイベントについて、どのような挙動になるか実際に動作するシンプルなアプリを[こちら](https://qiita.com/LJC-mobileapps/items/b2a3b98357364d708cbe)で紹介しています。
参考までに参照ください。
[Qiita記事：ブロックチェーン・ブリッジを実装してみる](https://qiita.com/LJC-mobileapps/items/b2a3b98357364d708cbe)
:::
## edevスタックの準備
ここでは、前回構築したBinance testnet bscスタックはとは別に、Fireflyの標準的な環境を使用します。
以下の手順によりスタックを構築します。
以下のコマンドにより、edevスタックの作成と起動を行います。
```bash
$ sudo service docker start
$ ff init
initializing new FireFly stack...
stack name: edev
You selected edev
number of members: 3
Stack 'edev' created!
To start your new stack run:

$ ff start edev

Your docker compose file for this stack can be found at: /home/ubuntu/.firefly/stacks/edev/docker-compose.yml
$ff start edev
done

Web UI for member '0': http://127.0.0.1:5000/ui
Sandbox UI for member '0': http://127.0.0.1:5109

Web UI for member '1': http://127.0.0.1:5001/ui
Sandbox UI for member '1': http://127.0.0.1:5209

Web UI for member '2': http://127.0.0.1:5002/ui
Sandbox UI for member '2': http://127.0.0.1:5309


To see logs for your stack run:

ff logs edev
```
## イベント受信の動作確認
イベント受信の動作確認は以下の手順で行います。
1. Browser WebSocket Clientを使用しFireFly WebSocketへ接続します。
2. Sandbox UIを使用してメッセージを送信します。
3. Browser WebSocket Clientでイベントの受信状態を確認します。
### イベント監視対象を指定
ChromeブラウザからBrowser WebSocket Clientを起動します。
ここではイベント監視対象として、Defaultネームスペースで発生する事象を監視します。
以下の文字列を入力して、WebSockへ接続します。
```ws://localhost:5000/ws?namespace=default&ephemeral&autoack&filter.events=message_confirmed```
#### 接続状態
ServerURLに上記wsアドレスを入力します。
Connectボタンをクリックすると、接続が行われセッションが開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/a0d536e6-2076-de58-b97b-157a633c8ab1.png)
### Sandbox UIからメッセージを送信
[BandBoxhttp http://127.0.0.1:5109をブラウザから開きます。](http://127.0.0.1:5109/home?action=messages.broadcast)
Messageエリアが表示されますので、送信するメッセージを入力します。
画面中央のjsonの内容に入力した文字列がセットされていることを確認し、Runボタンをクリックします。
ここで入力した文字列とともにイベントが発生します。イベントの状態は画面右側で確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/668bb58a-3783-b4aa-6583-c008ff84b549.png)
### イベント受信状態を確認
ChromeブラウザのBrowser WebSocket Client画面に戻ります。
画面を下にスクロールすると、メッセージが1件表示されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/aafb2aa4-b9e3-8485-9686-469c0c088b9d.png)
## イベントを受信する条件の指定
上記はメッセージ処理された際のエベントを全て受信していました。
ここでは、メッセージに含まれる特定の情報に合致した場合のみイベントを受信するようにします。
ここでのシナリオとして、メッセージを送信する際に**TAG項目に「RELAY」と指定されているメッセージのみハンドリングする**ようにします。
### サブスクリプションのセットアップ
特定の条件を受け取るためのサブスクリプションを登録します。
swaggerUIを開きます。
画面から[/namespaces/{ns}/subscriptionsを探します。](http://127.0.0.1:5000/api#/Non-Default%20Namespace/postNewSubscriptionNamespace)
以下のテキストを登録します。
"name"に"relay"を指定します。ここで入力した文字列をBrowser WebSocket Clientで監視する際のパラメータに指定します。
"tag"に"RELAY"を指定します。ここで入力した文字列がメッセージ受信時のフィルタとして処理されます。
```json
{
  "transport": "websockets",
  "name": "relay",
  "filter": {
    "blockchainevent": {
      "listener": ".*",
      "name": ".*"
    },
    "events": ".*",
    "message": {
      "author": ".*",
      "group": ".*",
      "tag": "RELAY",
      "topics": ".*"
    },
    "transaction": {
      "type": ".*"
    }
  },
  "options": {
    "firstEvent": "newest",
    "readAhead": 50
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/ad520278-ff6a-e842-5da9-b6cc5189f8ba.png)
### イベント監視対象を指定
ChromeブラウザからBrowser WebSocket Clientを起動します。
以下のnameにrelay文字列を入力して、WebSockへ接続します。
```ws://localhost:5000/ws?namespace=default&autoack&name=relay```
#### 接続状態
ServerURLに上記wsアドレスを入力します。
Connectボタンをクリックすると、接続が行われセッションが開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/9c1fe2b2-66cc-817f-9169-6bcc658d5d5c.png)
### Sandbox UIからメッセージを送信
[BandBoxhttp http://127.0.0.1:5109をブラウザから開きます。](http://127.0.0.1:5109/home?action=messages.broadcast)
Messageエリアが表示されますので、送信するメッセージを入力します。
ここで、**TAGエリアに「RELAY」を入力**します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/bf1bbe34-45fc-ad5f-e861-d049175277cf.png)
入力後、画面中央の「Run」ボタンをクリックしメッセージを送信します。
### イベント受信状態を確認
ChromeブラウザのBrowser WebSocket Client画面に戻ります。
画面を下にスクロールすると、メッセージが1件表示されていることが確認できます。
なお、TAGにRELAY以外の文字列(NONEなど)を入力して送信するとイベントが表示されないことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/a59f5d0a-2e22-f7b2-f5ff-a6264a9b7458.png)

イベントの動作確認は以上です。
## 次回は
今回は、イベントの扱いについて紹介しました。
イベントをハンドリングする方法やサブスクリプションのフィルタの定義など、用意されているパラメータを確認すると、さらに多くの条件を指定することが可能のようです。今回の動作確認はここまでにしたいと思います。
次回は、カスタムスマートコントラクトの登録と利用について紹介する予定です。