Azure Blockchain機能を用いてコンソーシアムチェーンとRDBを相互運用する

Naochika Hanamura
LayerX-jp
Published in
16 min readMay 19, 2020

はじめに

はじめまして。LayerXを手伝っています花村(@naomasabit)です。ブロックチェーン領域でサービスをいくつか開発したり、EthereumでNFTやセキュリティトークンコントラクトの開発などを行ってきました。

AzureではEnterprise EthereumのQuorumを簡単に立てることができ、うまくパーツを組み合わせることでRDBにデータを逐次同期させることができます。

コンソーシアムブロックチェーン運用時の課題

エンタープライズでコンソーシアムブロックチェーンを運用する際の課題はいくつかありますが、

  • ノード構築の手間
  • コンソーシアム参加メンバー管理の煩雑さ
  • ブロックチェーン上のデータを検索しやすくするための基盤づくり

などがあります。これらについてAzureは解決策を用意してくれています。

まず、ノード構築の手間とコンソーシアム参加メンバー管理についてはAzure Blockchain Serviceを用いることで簡単に立てることができ、Managedで運用ができます。

ブロックチェーンデータの検索難易度については、ブロックチェーンノードのままだと検索が難しいのですが、今回作成するパイプラインによってAzure Blockchain ServiceからRDBへ逐次同期を行うことができます。

Azure BlockchainからRDBへの同期の全体像について

Azure Blockchain ServiceはAzure上で動くマネージドなブロックチェーンノードです。

Azure上で動くBlockchain Data ManagerがAzure Blockchain Serviceからデータを抽出し、Event Gridというイベントハンドラに流し込みます。

Event Gridは各種リソースに連携し、LogicAppsと呼ばれるデータ加工ロジックやCosmos DB、MySQLといったDBへ連携します。

(参考)blockchain data managerの説明動画
https://www.youtube.com/watch?v=TQ5wWIQLC_A

今回作るパイプラインは以下のようになります。

Azure Blockchain Serviceでコンソーシアムチェーンを立てる

Azure Blockchain ServiceではQuorumでコンソーシアムチェーンを立てることができます。以下3つがコンソーシアムの主要な構成要素です。

  • consortium: コンソーシアム
  • member: コンソーシアム所属メンバ。コンソーシアムは複数のメンバを持つ
  • node: memberが動かすノード。1メンバに対して複数持てる

Azure上のコンソールではコンソーシアム、メンバを追加してコンソーシアムチェーンを作成することができます。

Azure Blockchain Data Managerでブロックチェーンデータの抽出設定を行う

Azure Blockchain Data Managerはデータを抽出する元と、送る先のエンドポイントを設定することができます。今回はEventGridをあらかじめ作っておき、送る先として指定しています。

また、Watchするコントラクトを設定します。コンパイルするときにできるABIとバイトコードをアップロードしてBlockchain Data Managerに読み込ませます。

ちなみにEventGridは、Azureの各種イベントに反応して動くトリガーです。Pub/SubやServerless Functionへの中継的な使い方ができます。今回はLogicAppsへのトリガーとして使うだけです。

Azure Blockchain DataManagerはどのようなデータを抽出してくれるのか

パイプライン構築の途中ですが、Azure Blockchain Data Managerについては深掘りしておきます。上記ではブロックの情報しか入っていませんでしたが、Azure Blockchain Serviceにどのようなデータを送ってくれるのかを紹介します。

Azure Blockchain DataManagerでは、抽出するデータのタイプに、MessageTypeを振っています。MessageType:RawBlockAndTransactionMsgの場合、ブロックとその中のトランザクション群を抽出してくれます。

以下はMessageTypeがRawBlockAndTransactionMsgのデータの抜粋です。ブロックチェーンのデータを見たことがある方は、ブロックとトランザクションが入っていることがわかると思います。

つまり原理的には、これらのデータをパースして自動的にRDBに登録していくことで、トランザクションの必要な項目をテーブルに分けて登録することなどが可能です。

{
...
"data": {
"BlockNumber": 382545,
"BlockHash": "0xb58a1a8be2260b816ae1c9b83202d1920c480516fe064ef3e879f7ae1f81e8bd",
"ParentHash": "0xd87b23bb282227330060212b0d813865696757b602cff6b42efae98fd3e617fb",
"Nonce": "0x0000000000000000",
"Sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"LogsBloom": "0x00000000000000000000000000000000000000000000000000000000000000200008000000000000000000000000004000000000000000000000000000000000000000000000000000000008000000000040000000000100000000000000000000000000020000000000000002000800000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100002000000000000000000000000000000000000000060000000000020000000000000000000000000000000000000000000000000000000000000000000",
"TransactionsRoot": "0x9de7a097690c5ec431d8438128fc739d2c551884429fcaa6108f907c30fdd076",
"ReceiptsRoot": "0xf5670f3f3ea6bd428b54f24afa190998f10839a86c642b55238d71fa02f1efa0",
"Miner": "0x0000000000000000000000000000000000000000",
"Difficulty": 1,
"TotalDifficulty": 382546,
"ExtraData": "0xd883010812846765746888676f312e31302e38856c696e757800000000000000f8b3ea941cc386648570f49df89e0c8f6e3be0f7ffb7361694c1acc49b0c2d7463f1f4a18d95854e04090a1c26b84198586990f46b57303b48eaff2020af17c4be306f1fdb11e91851e1aebd9330ed1089d37b08bb4fc8cc58ad3e2f8dd02beac6b1f3c921888b9a7e96e6233d7e7500f843b8410c729bc2379817d6e7d9d2e1dfe0b23f8146d4b4259a2b5014527df32bf7eaf179fac9fbc28982b88e4aaefe5045f1bfa15e3bbe11e42994bd2c075752c680f001",
"Size": 897,
"GasLimit": 700000000,
"GasUsed": 143526,
"BlockTimestamp": 1582618677,
"Transactions": [
{
"From": "0x901a2c7135b5adcc269f72fe7246c6829fbad022",
"Gas": 6721975,
"GasPrice": 0,
"Hash": "0xe2de7f11a264ac5afd9dba05e46a465a2133bb2cd6a239c6c4737e9b638ca7fa",
"Input": "0x40c10f19000000000000000000000000901a2c7135b5adcc269f72fe7246c6829fbad0220000000000000000000000000000000000000000000000000000000000000018",
"Nonce": 119,
"To": "0x3d04b01c19de7368fbc2be519b6b6b0c462e1ac7",
"TransactionIndex": 0,
"Value": 0,
"GasUsed": 143526,
"CumulativeGasUsed": 143526,
"Status": 1,
"Logs": [
{
"Topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x000000000000000000000000901a2c7135b5adcc269f72fe7246c6829fbad022",
"0x0000000000000000000000000000000000000000000000000000000000000018"
],
"Address": "0x3d04b01c19de7368fbc2be519b6b6b0c462e1ac7",
"Data": "0x",
"LogIndex": "0x0"
}
]
}
],
"ScheduleOffsetMillisec": 0,
"MessageId": "e1516777-38a0-4fbd-9225-bdf8c1bc175b",
"MessageType": "RawBlockAndTransactionMsg",
...
},
...
}

MessageType:DecodedContractEventsMsgの場合、イベントログがデコードされた状態で出力されます。以下はERC721トークンのMintイベントを叩いた時のイベントログです。重要なイベントログがデコードされて出力されるため、このメッセージを加工することでRDBにイベントログのテーブルとして登録することも可能です。

{
...
"data": {
"TransactionHash": "0x167a31733bcd126a628251a21fc8cb69bf3f8eef2b647c5272ec31239e62449f",
"BlockHash": "0x526b9e01fb41d8a81de2ce5a81c9fff7e38b49cf2383f8ccdb77fc328326f12c",
"BlockNumber": 382504,
"ContractAddress": "0x3d04b01c19de7368fbc2be519b6b6b0c462e1ac7",
"EventName": "Transfer",
"EventValue": [
{
"ParameterName": "from",
"ParameterType": "address",
"ParameterValue": "0x0000000000000000000000000000000000000000",
"Indexed": true
},
{
"ParameterName": "to",
"ParameterType": "address",
"ParameterValue": "0x901a2c7135b5adcc269f72fe7246c6829fbad022",
"Indexed": true
},
{
"ParameterName": "tokenId",
"ParameterType": "uint256",
"ParameterValue": "17",
"Indexed": true
}
],
"RawTopicHex": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"BlockTimestamp": 1582618472,
"ScheduleOffsetMillisec": 0,
"MessageId": "e3499e1d-d8a1-4fc5-b67f-48f414477470",
"MessageType": "DecodedContractEventsMsg",
...
},
...
}

LogicAppsの作成

LogicAppsはAzureの各種タスクを組み合わせてフローを作成できるツールです。今回は加工なしでEventGridからSQLDBに入れるLogic Appsのフローを作成します。

EventGridをInputとして、Azure SQL DBのInsert Rowをアクションとして選択。これにより、Azure SQL DBのテーブルにデータが入ります。

上の画像は、ブロック生成時のデータを受け取ってInsertした時のデータです。ローカル環境からSQLDBに接続してSQLで選択してみると、以下のようにデータが入っていることがわかります。何も加工していないため、idカラムにBlockNumberやBlockHashなどのJsonがそのまま入っていますが、LogicAppsで加工をすることでカラムに情報をマッピングすることなどができます。

まとめ

Azure Blockchain Serviceを用いてQuorumのコンソーシアムノードを簡単に立てられること、そしてデータの検索性を向上させるためにRDBと逐次同期する方法を紹介しました。

Azure Blockchain ServiceもAzure Blockchain Data Managerも執筆時点(2020/4/20)のところPreview版ですが、コンソーシアムノード運用で問題となる点をサポートしてくれる機能を持っています。

これ以外にもLayerXではコンソーシアムチェーン構築ノウハウを数多く持っているチームです。コンソーシアムチェーン構築の検討をされている企業様は LayerXコンタクトフォームよりご連絡ください。

https://forms.gle/6hFcg8xZoa8HXuiL6

参考リンク

Azure Blockchain Serviceの開発者向けドキュメント

Azure Blockchain Data Managerの開発者向けドキュメント

--

--