フィルターを使用すると、クラウドサービス統合トリガーにプッシュされるブロックチェーンデータを制御し、その形式を調整できます。フィルターを使用すると、関連性のないイベントを破棄したり、特定のフィールドを抽出したり、ペイロードをダウンストリームサービスが期待する形式に変換したりできます。すべてのフィルター式は、jq 構文を使用します。Fabric イベントデータ構造の詳細については、「Fabric サンプルメッセージ」をご参照ください。
フィルターパターン概要
フィルター式は、受信する各ブロックチェーンイベントに適用される jq パイプラインです。この式は、次の3つのことができます。
| 目的 | jq パターン | 例 |
|---|---|---|
| 条件によるフィルター | select(...) | 条件に一致しないイベントを破棄する |
| フィールドの抽出 | | .fieldName | イベントの一部のみをプッシュする |
| 変換と再形成 | | map(...) | データベース挿入のための再構築 |
これらを組み合わせることもできます。select(...) | .fieldName は、最初にフィルター処理を行い、次に抽出します。
クラウドサービス統合トリガーを設定する際に、[詳細オプション] にフィルター式を入力します。
ヒント: デプロイする前に、jq 式をローカルでテストしてください。トリガーを設定する前に、ターミナルで echo '<event-json>' | jq '<your-expression>' を実行して出力を確認します。前提条件
開始する前に、以下があることを確認してください。
スマートコントラクトがデプロイされた Fabric チャンネル
ターゲットが設定されたクラウドサービス統合トリガー (このページでは Function Compute を例として使用しています)
ローカルにクローンされた クラウドサービス統合サンプルコード
サンプル環境のセットアップ
以下の手順は、Function Compute でフィルター式をテストするための作業環境を準備します。
クラウドサービス統合サンプルコードをダウンロードします。
Function Compute (FC) 用の Serverless Devs ツールをインストールします。「Serverless Devs の概要とインストール」をご参照ください。
event-with-filterディレクトリに移動し、s deployを実行して、関数を FC にデプロイします。FC コンソールにログインし、
LoggerFunc関数のログクエリを有効にします。
サンプルチェーンコード taskmgr をチャンネルにデプロイします。「チェーンコードのデプロイ」をご参照ください。
クラウドサービス統合トリガーを設定します。
ヘルプドキュメントに記載されているとおりに、FC インスタンスの詳細を入力します。
[詳細オプション] で、以下のサンプルシナリオからフィルター式を入力します。
blockchain2smsディレクトリに移動し、main.jsを開き、インラインコメントに基づいてパラメーター (REST API アドレス、トークンの更新、チャンネル名、スマートコントラクト名) を更新します。「REST API の使用」をご参照ください。npm installを実行して依存関係をインストールし、次にnode main.jsを実行してサンプルトランザクションを送信します。FC ログをチェックしてイベントコンテンツを検査します。
サンプルシナリオ
以下の例では、channel3 にデプロイされた taskmgr スマートコントラクトを使用します。
名前によるイベントのプッシュ
スマートコントラクトイベント名が event-create-task である Contract イベントのみをプッシュします。
イベントタイプ: Contract
フィルター:
select(.name=="event-create-task")
| 入力イベントフィールド | 値 |
|---|---|
name | "event-create-task" |
platform | "Fabric" |
network | "channel3" |
type | 8 |
プッシュされたデータ:
{
"content": "eyJuYW1lIjoidGFzay0xNTgwOTcxODQyOTM3IiwiY3JlYXRvciI6ImUyZWhtZnFhc3RoTVNQLm9jdG9wdXNfMjY4NDJfMTIzNDU2Nzg5MDEyMzQiLCJyZXF1aXJlcyI6WyJlMmVobWZxYXN0aE1TUC5vY3RvcHVzXzI2ODQyXzEyMzQ1Njc4OTAxMjM0Il0sImFwcHJvdmVkIjpudWxsLCJkZXNjcmlwdGlvbiI6IuekuuS+i+S7u+WKoe+8jHJlcXVpcmVzIOmFjee9ruWuoeaJueS7u+WKoeWujOaIkOmcgOimgemCo+S6m+eUqOaIt+WQjOaEj+OAgueUqOaIt+aPj+i/sOS4uiAn57uE57uHTVNQLueUqOaIt+WQjeensCcifQ==",
"id": "contract-131-ca144c3385f56a429b9e8874173f7c97fbb49de69f931aec583ec50222a3a2ed",
"instance_id": "csi-e2ehmfqasth-bcw7tzao2dzeo",
"name": "event-create-task",
"network": "channel3",
"platform": "Fabric",
"type": 8
}特定のコントラクトに対する有効なトランザクションのプッシュ
taskmgr スマートコントラクトに送信された有効なトランザクションのみをプッシュします。
イベントタイプ: Tx
フィルター:
select(.content.to=="taskmgr" and .content.state=="VALID")
| フィルター条件 | フィールドパス | 値 |
|---|---|---|
| ターゲットコントラクト | .content.to | "taskmgr" |
| トランザクションの状態 | .content.state | "VALID" |
プッシュされたデータ:
{
"content": {
"events": ["event-create-task"],
"from": "e2ehmfqasthMSP.octopus_26842_12345678901234",
"id": "3a2e0e375c6ee0d9c6c20d756e787db44d50bfeba51f22d8f262dd1556dedba0",
"input": "[\"create\",\"task-1580971842937\",\"{\\n \\\"requires\\\": [\\\"e2ehmfqasthMSP.octopus_26842_12345678901234\\\"],\\n \\\"description\\\": \\\"Sample task. Task completion requires the approval of certain users. The user is described as 'Organization MSP. User name'\\\"\\n }\"]",
"state": "VALID",
"to": "taskmgr"
},
"id": "tx-128-3a2e0e375c6ee0d9c6c20d756e787db44d50bfeba51f22d8f262dd1556dedba0",
"instance_id": "csi-e2ehmfqasth-bcw7tzao2dzeo",
"name": "3a2e0e375c6ee0d9c6c20d756e787db44d50bfeba51f22d8f262dd1556dedba0",
"network": "channel3",
"platform": "Fabric",
"type": 2
}部分イベントペイロードのプッシュ
スマートコントラクトイベント名が event-create-task である Contract イベントから、content フィールドのみをプッシュし、他のすべてのフィールドは破棄します。
イベントタイプ: Contract
フィルター:
select(.name=="event-create-task") | .content
プッシュされたペイロードは、content フィールドに格納されている生の Base64 文字列です。
"eyJuYW1lIjoidGFzay0xNTgwOTcxODQyOTM3IiwiY3JlYXRvciI6ImUyZWhtZnFhc3RoTVNQLm9jdG9wdXNfMjY4NDJfMTIzNDU2Nzg5MDEyMzQiLCJyZXF1aXJlcyI6WyJlMmVobWZxYXN0aE1TUC5vY3RvcHVzXzI2ODQyXzEyMzQ1Njc4OTAxMjM0Il0sImFwcHJvdmVkIjpudWxsLCJkZXNjcmlwdGlvbiI6IuekuuS+i+S7u+WKoe+8jHJlcXVpcmVzIOmFjee9ruWuoeaJueS7u+WKoeWujOaIkOmcgOimgemCo+S6m+eUqOaIt+WQjOaEj+OAgueUqOaIt+aPj+i/sOS4uiAn57uE57uHTVNQLueUqOaIt+WQjeensCcifQ=="トランザクションからのライトセットの抽出
有効な taskmgr トランザクションによって書き込まれたすべてのキーのライトセットをプッシュします。
イベントタイプ: Tx
フィルター:
select(.content.state=="VALID" and .content.to=="taskmgr") | .content.data.data.actions.[0].payload.action.proposal_response_payload.extension.results.ns_rwset[] | select(.namespace=="taskmgr") | .rwset.writes
このフィルターは、Fabric リードライトセットを深く掘り下げ、taskmgr 名前空間の書き込みのみを返します。プッシュされたデータ:
[
{
"is_delete": false,
"key": "\u0000e2ehmfqasthMSP.octopus_26842_12345678901234\u0000task-1581479306267\u0000",
"value": "eyJuYW1lIjoidGFzay0xNTgwOTcxODQyOTM3IiwiY3JlYXRvciI6ImUyZWhtZnFhc3RoTVNQLm9jdG9wdXNfMjY4NDJfMTIzNDU2Nzg5MDEyMzQiLCJyZXF1aXJlcyI6WyJlMmVobWZxYXN0aE1TUC5vY3RvcHVzXzI2ODQyXzEyMzQ1Njc4OTAxMjM0Il0sImFwcHJvdmVkIjpudWxsLCJkZXNjcmlwdGlvbiI6IuekuuS+i+S7u+WKoe+8jHJlcXVpcmVzIOmFjee9ruWuoeaJueS7u+WKoeWujOaIkOmcgOimgemCo+S6m+eUqOaIt+WQjOaEj+OAgueUqOaIt+aPj+i/sOS4uiAn57uE57uHTVNQLueUqOaIt+WQjeensCcifQ=="
}
]特定のキーの監視
有効な taskmgr トランザクションにおける特定のキーの値の変更を監視します。
イベントタイプ: Tx
フィルター:
select(.content.state=="VALID" and .content.to=="taskmgr") | .content.data.data.actions.[0].payload.action.proposal_response_payload.extension.results.ns_rwset[] | select(.namespace=="taskmgr") | .rwset.writes[] | select(.key=="special_key")
このフィルターは、単一のキーに一致させることで、前のシナリオのライトセットの抽出を拡張します。プッシュされたデータ:
{"is_delete": false, "key": "special_key", "value": "MTA="}トランザクションデータをデータベーステーブルにエクスポート
ブロックチェーンデータを、データベース挿入の準備ができたオブジェクトの配列に変換します。各オブジェクトは1つの行を表し、キーはカラム名です。
期待される出力形式:
[
{
"columnName1": "value1",
"columnName2": "value2",
"columnName3": "value3"
}
]ターゲットテーブル構造:
| カラム | 説明 |
|---|---|
event_id | イベント ID |
namespace | スマートコントラクト名 |
key | 台帳に書き込まれたキー |
value | Base64 エンコーディングの値 |
create_time | 書き込みのタイムスタンプ |
tx_id | トランザクション ID |
is_delete | 操作が削除であるかどうか |
creator | トランザクションの開始者 |
プライマリキー: (event_id, namespace, key)
イベントタイプ: Tx
フィルター:
select(.content.state=="VALID" and .content.to=="taskmgr") | .id as $eventID | .content.id as $txID | .content.from as $creator | content.data.header.channel_header.timestamp as $createTime | .content.data.data.actions.[0].payload.action.proposal_response_payload.extension.results.ns_rwset | ap(.namespace as $namespace | .rwset.writes | map( .event_id = $eventID | .namespace = $namespace | .tx_id = $txID | .create_time = $createTime | .creator = $creator )) | dd
サンプルエクスポートデータ:
[
{
"event_id": "tx-128-3a2e0e375c6ee0d9c6c20d756e787db44d50bfeba51f22d8f262dd1556dedba0",
"namespace": "taskmgr",
"tx_id": "3a2e0e375c6ee0d9c6c20d756e787db44d50bfeba51f22d8f262dd1556dedba0",
"is_delete": false,
"key": "\u0000e2ehmfqasthMSP.octopus_26842_12345678901234\u0000task-1581479306267\u0000",
"value": "eyJuYW1lIjoidGFzay0xNTgwOTcxODQyOTM3IiwiY3JlYXRvciI6ImUyZWhtZnFhc3RoTVNQLm9jdG9wdXNfMjY4NDJfMTIzNDU2Nzg5MDEyMzQiLCJyZXF1aXJlcyI6WyJlMmVobWZxYXN0aE1TUC5vY3RvcHVzzI2ODQyXzEyMzQ1Njc4OTAxMjM0Il0sImFwcHJvdmVkIjpudWxsLCJkZXNjcmlwdGlvbiI6IuekuuS+i+S7u+WKoe+8jHlcXVpcmVzIOmFjee9ruWuoeaJueS7u+WKoeWujOaIkOmcgOimgemCo+S6m+eUqOaIt+WQjOaEj+OAgueUqOaIt+aPj+i/sOS4uiAn57uE57uHTVNQLueUqOaIt+WQjeensCcifQ==",
"create_time": "2020-02-06T06:50:42.267092Z",
"creator": "e2ehmfqasthMSP.octopus_26842_12345678901234"
}
]次のステップ
REST API の利用 — BaaS REST API を呼び出してトランザクションを送信し、データをクエリします
チェーンコードのデプロイ — チェーンコードをチャンネルにデプロイします
jq マニュアル — jq の構文に関する完全なリファレンス