Amazon Web Services ブログ

Amazon Managed Blockchain でイベントベースのアプリケーションをビルドする



Amazon Managed Blockchain 上にビルドされたアプリケーションで、信頼できる環境で複数の当事者が相互にトランザクションを実行できるようになりました。これは、各当事者がブロックチェーンにコミットする前にトランザクションを承認できるようになったためです。ブロックチェーンイベントによってアプリケーションはアクティビティへの応答が可能になります。また、ブロックの新規作成などのブロックチェーンネットワークのアップデート、さらにはネットワークにデプロイされたスマート契約書のアップデートの応答もできるようになります。

ブロックチェーンイベントは非常に有用で、さまざまなアクティビティを可能にします。例としては、Amazon Simple Notification Service (Amazon SNS) によるビジネスイベント発生時のユーザー通知、Amazon QuickSightAmazon Redshift などのビジネスインテリジェンスおよびビジネス分析エンジンへのデータのストリーミングが挙げられます。Amazon DynamoDBAmazon Aurora などの専用データベースにストリーミングしたり、イベントトリガー型アプリケーションには AWS Lambda を使用したりもできます。

Hyperledger Fabric ブロックチェーンネットワークでは、ブロックチェーンネットワークアクティビティをモニタリングするための 3 種類のイベントタイプがあります。

  • ブロックイベント – 新規ブロックが台帳に追加されたときに発生します。ブロックイベントには、ブロックが持つトランザクション情報が含まれます。
  • トランザクションイベント – トランザクションが台帳にコミットされたときに発生します。
  • チェーンコードイベント – チェーンコードとは、ブロックチェーンネットワークで実行されるアプリケーションコードのことです。これにより、台帳とのインタラクションが可能になります。チェーンコード内でイベントを定義できるうえに、イベントのトリガーとなる条件を定義できます。イベントは、必要な条件を備えたブロックが台帳にコミットされるとトリガーされます。

本記事では、透明性の高い NGO の寄付アプリケーションのユースケースを説明します。寄付金を NGO がどう活用しているかが寄贈者にわかるようなアプリケーションの作成と構成の詳細は、Github リポジトリをご覧ください。本記事では、新規寄付が SMS でユーザーに通知されるように、アプリケーションをビルドしていきます。Amazon Managed Blockchain でチェーンコードイベントを使ったワークフローのビルド方法や、Amazon SNS を使った SMS メッセージの送信方法を説明します。

ソリューションの概要

次の図は、本ソリューションのアーキテクチャを示しています。

本ソリューションの主なステップは、以下のとおりです。

  • ブロックチェーンイベントリスナーを AWS Fargate タスクとしてデプロイする
  • リスナーを Managed Blockchain ネットワークのピアノードに接続、登録し、ブロックチェーンイベントの通知が届くようにする
  • リスナーからのブロックチェーンイベントを Lambda 関数が処理できるように Amazon Simple Queue Service (Amazon SQS) に送信する
  • SMS メッセージを送信する Amazon SNS に、ブロックチェーンイベントをメッセージとしてパブリッシュする

ブロックチェーンイベントリスナー

Node.js アプリケーションであるブロックチェーンイベントリスナーでは、Node.js Fabric SDK を使用して Fabric ピアノードに接続、登録し、ブロックチェーンイベントを通知します。リスナーがピアノードに接続すると、接続する Fabric ユーザーおよび関心のあるイベントタイプがピアノードによって指定されます。ユーザー認証情報はプライベートキーと公開証明書からなり、AWS Secrets Manager に保存されます。

このユースケースでは、イベントリスナーを登録して、NGO が寄付を受領したときにトリガーとなるチェーンコードイベントをリッスンします。チェーンコードイベントはイベントリスナーによって SQS キューにパブリッシュされます。

Node.js リスナーアプリケーションはコンテナイメージとしてパッケージ化されており、Amazon Elastic Container Registry (Amazon ECR) に保存されます。リスナーアプリケーションは、Amazon Elastic Container Service (Amazon ECS) サービスで Fargate タスクとして実行されます。Fargate タスクとしてリスナーを実行するとオペレーション経費が削減されますが、これはリスナーによって Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのプロビジョニングとメンテナンスの必要性がなくなるうえに、ECS サービス内で実行することでエラー発生時の自動再起動が可能になるためです。このユースケースでは、パブリックインターネットから直接アクセス可能にする必要がないため、Fargate タスクを VPC 内のプライベートサブネットで実行します。

Fargate タスクが起動されると、ピアノードに接続される前にユーザー認証情報が Secrets Manager からダウンロードされます。

デフォルトでは、リスナーにはブロックチェーンの作成以降に発生したイベントすべてが通知されます。つまり、リスナーが再起動されると、同じイベントが再び処理されます。この事象に対処するために、リスナーは (DynamoDB などで) 処理した最後のブロックを存続させて、リスナーが再起動された際に新規のイベント通知の開始ポイントが指示されるようにします。これを設定するには、リスナー登録の際に付与される RegistrationOpts オブジェクト内の startBlock 属性を使用します。

Lambda イベントハンドラー

SQS キューにパブリッシュされたチェーンコードイベントは、Lambda 関数によって処理されます。イベントデータを使用する Lambda 関数によって、SMS メッセージ本文が作成され、Amazon SNS が呼び出されて、通知メッセージが送信されます。

チェーンコードのアップグレード

Fabric NGO チェーンコード はアップグレードされると、寄付が発生したときにチェーンコードイベントが出力されます。これには、Node.js Fabric SDK を使用します。次のコード例を参照してください。

function createEvent(stub, data = {}) {
  const eventObject = {
      createdAt: (new Date()).getTime(),
      createdBy: data.donor,
      donationAmount: data.amount
  }
  stub.setEvent(data.eventName, Buffer.from(JSON.stringify(eventObject)));
}

チェーンコードをアップグレードためのステップは 2 つです。

  • ピアノードにチェーンコードをインストールする
  • チャネルのチェーンコードをアップグレードする

このユースケースではピアノードを 1 個実行しますが、ピアノードを複数実行したり、ネットワーク上で複数のメンバーと実行したりする場合は、各ピアノードにチェーンコードをインストールする必要があります。チェーンコードのアップグレードは 1 回は実行する必要があります。

前提条件

各ステップの説明の前に、GitHub リポジトリの非営利団体向けワークショップのパート 1パート 2 を済ませておく必要があります。両パートには、Managed Blockchain ネットワークの作成、管理者権限を持つユーザーの登録、NGO チェーンコードのデプロイが含まれています。

ステップの概要

このプロセスの各ステップの詳細については、GitHub リポジトリを参照してください。本記事の各ステップにはリポジトリと同様に、ステップの完了に必要なスクリプトやコマンドの実行といったステップがあります。各ステップを読みながら、リポジトリのほうの該当ステップも参照していただくと、理解がより深まります。

説明は、次のステップからなります。

  1. ピアイベントをリッスンする Fabric ユーザーを作成する
  2. コンテナイメージの Node.js リスナーを Amazon ECR にデプロイする
  3. SQS キューをデプロイする
  4. Fargate タスクをホストする ECS サービスをデプロイする
  5. リスナーを実行する Fargate タスクをデプロイする
  6. SMS サブスクリプションで SNS トピックを作成する
  7. あらゆるイベントを Amazon SNS にパブリッシュする Lambda 関数をデプロイする
  8. チェーンコードイベントを出力するチェーンコードをアップグレードする

ステップ 1: ピアイベントをリッスンする Fabric ユーザーを作成する

Hyperledger Fabric ピアノードによってブロックが処理され、イベントが出力されます。イベントリスナーが登録されてイベント通知を受信するようになります。イベントリスナーを登録するには、ユーザー認証情報を使ってピアに接続する必要があります。

このステップでは、ユーザーを参加登録します。ユーザーを登録すると、ユーザーの組織の認証機関にユーザーのエントリが作成されます。ユーザーを登録すると、トランザクションの署名に使用できる認証情報が生成されます。認証情報は、ピアノードによるイベントリスナーの登録にも使用できます。

ユーザーを登録すると、以下のアーティファクトが生成されます。

  • プライベートキー
  • 署名証明書 (パブリックキー)

両アーティファクトは Secrets Manager に保存され、Fargate タスクによってタスク実行中にダウンロードされます。

詳細については、「Register and Enroll a User as an Administrator」を参照してください。

ステップ 2: コンテナイメージの Node.js リスナーを Amazon ECR にデプロイする

イベントリスナーは継続的に実行される必要があるため、イベント通知が発生するたびに受信します。リスナーを実行するには、ECS サービスによって管理されるコンテナイメージ内でリスナーをパッケージ化します。コンテナイメージは、ECS サービスがプルできるプライベート Amazon ECR リポジトリにパブリッシュされます。

本番環境で高い可用性を実現するために、このコンテナのインスタンスを複数実行することもできます。

ステップ 3: SQS キューをデプロイする

ブロックチェーンイベントの耐久性を強化するために、イベントリスナーによってブロックチェーンイベントが SQS キューに書き込まれ、当該イベントは Lambda 関数の処理待ちに入ります。SQS キューにイベントをメッセージとして保存すると、Lambda 関数によるメッセージ処理でエラーが発生した場合にエラーのハンドリングが円滑に進みます。メッセージ処理を再試行して再びエラーが発生したら、当該メッセージはデバッグのインスペクションができるように Amazon SQS によってデッドレターキュー (DLQ) に移動されます。

ブロックチェーンイベントを直接 SNS トピックに送信すると、SQS キューの必要がなくなり、コストが削減されます。Amazon SNS がサポートする DLQ では、サブスクリプションエンドポイントが到達不能になった場合にメッセージを保存できるため、アプリケーションの回復性が強化されます。このアプローチはコスト効率によりすぐれており、本番環境では推奨されます。詳細は、「サブスクリプションの Amazon SNS デッドレターキューを設定する」をご覧ください。

本記事では、SQS キューを使用し、この機能を拡張してさまざまなサービスと統合する方法を説明します。

ステップ 4: Fargate タスクをホストする ECS サービスをデプロイする

ECS サービスが管理する Fargate タスクとしてイベントリスナーを実行すると、サーバーレスアーキテクチャを使用できるようになり、サーバーの管理やプロビジョニングの必要がなくなります。アプリケーションは、Fargate セキュリティモデルによって設計ごとに分離されます。

ステップ 5: リスナーを実行する Fargate タスクをデプロイする

Amazon ECS では 1 つのサービス内のタスク数をスケーリングして要求を満たすことができますが、リスナーでは当該サービス内の 1 つのタスクとしてインスタンス作成されます。サービスは少なくとも 1 個のタスクで定義されるため、エラーが発生してもタスクは自動的に再起動されます。ブロックチェーンイベントはブロックチェーン上で存続するため、リスナータスクが再起動されると、読み込まれたもっとも最近のブロックからイベント消費が開始されます。

ステップ 2 でアップロードしたコンテナイメージを使用する Fargate タスクを作成します。このタスクではイメージを実行するコンテナの設定、たとえばロギングのオプションや Node.js イベントリスナーが使用する環境変数などが定義されます。

ここまでで、ブロックチェーンイベントをリッスンして、あらゆるイベントを Amazon SQS にパブリッシュする Fargate タスクとして実行されるリスナーができました。イベントは、Lambda 関数を使用してハンドリングできます。さまざまな AWS のサービスも、Lambda 関数から起動できます。たとえば、DynamoDB や Amazon Simple Storage Service (Amazon S3) にブロックチェーンイベントデータを書き込んで、クエリ時間を短縮し、Amazon QuickSight ダッシュボードを駆動できます。このユースケースでは、Amazon SNS を使用して、新規寄付の SMS 通知を送信します。

ステップ 6: SMS サブスクリプションで SNS トピックを作成する

可用性および耐久性の高いメッセージングサービスである Amazon SNS は、疎結合化されたマイクロサービス間でのメッセージのやりとりや、モバイルプッシュ通信、SMS、E メールによるエンドユーザーへの通知の送信に使用できます。メッセージは、関心を持っている当事者がサブスクリプションできるトピックに送信されます。このステップでは、「新規寄付」メッセージというトピックを作成して、携帯電話番号による SMS 通知を受信できるようにサブスクリプションします。詳細は「SMS メッセージの送信」をご覧ください。

このユースケースでは、あらゆる寄付イベントに関する SMS を受信します。しかし、現実のアプリケーションではどのメッセージがどのユーザーに届くかコントロールする際に、フィルターを使用することが多いかもしれません。

ステップ 7: あらゆるイベントを Amazon SNS にパブリッシュする Lambda 関数をデプロイする

SQS キューの各ブロックチェーンイベントは、Lambda 関数のトリガーとなります。イベントデータは Lambda 関数によって解析され、対応するメッセージが Amazon SNS にパブリッシュされます。当該メッセージは、Amazon SNS によってサブスクリプション経由で SMS に転送されます。

ステップ 8: チェーンコードイベントを出力するチェーンコードをアップグレードする

ここまでに実行してきたすべてのステップは、ブロックチェーンネットワークの外部でした。最後のステップでは、Fabric ネットワークのチェーンコードをアップグレードして、createDonation 関数が呼び出されたらいつでもイベントを出力するようにします。チェーンコードのソースコードがアップグレードされたら、あらゆるピアノードにインストールする必要があります。ブロックチェーンメンバーは一般に、高い可用性と耐障害性のためにピアノードを複数持っているため、チェーンコードはすべてのピアノードにデプロイすべきです。

すべてのメンバーがピアノードにチェーンコードをインストールしたら、チャネルのチェーンコードをアップグレードします。

テスト

すべてのコンポーネントがプロビジョニングされ、テストの準備が整いました。ソリューションをテストするには、次のステップを実行します。

  1. ブロックチェーントランザクションを発行して、NGO を作成し、チェーンコードの createNGO 関数を起動する
  2. チェーンコードイベントを出力するために新規コードを追加した createDonation 関数を起動して、寄付を作成する
  3. すべての動作が正常である場合、即座に SMS が届くことになっています

SMS を受信していない場合は、SQS キューをチェックします。DLQ 内にメッセージがあった場合は、Lambda 関数が動作しなかった原因をインスペクションします。メッセージがどこにも見あたらない場合は、リスナーの問題である可能性があります。詳細については、Fargate コンテナの Amazon CloudWatch Logs をご覧ください。

まとめ

本記事では、AWS Fargate で実行される Hyperledger Fabric ブロックチェーンイベントリスナーのデプロイ方法を説明しました。また、Lambda 関数をデプロイして、チェーンコードを処理し、Amazon SNS 通知をパブリッシュして SMS メッセージを送信しました。

次のステップとしては、異なるイベントリスナーを書き込み、イベントデータを Amazon S3 データレイクに送信して、Amazon QuickSight によってブロックチェーンデータからインサイトを取得することが考えられます。このビルドにあたっては、ステップ 7 でデプロイした Lambda 関数を、Amazon S3 にイベントデータを書き込む Lambda 関数に置き換えることになります。その方法を紹介する記事は近日中に公開予定です。

 


著者について

 

Emile は AWS のシニアブロックチェーンアーキテクトです。自由時間には、サンフランシスコ北部の丘でトレイルランニングを楽しみ、18 か月の娘に遅れをとらないように頑張っています。