Azure Blockchain Service でできることをステップバイステップでザックリと理解する！

※本記事は2020年5月6日時点の情報を元に書かれています。

#はじめに
[Azure Blockchain Service](https://azure.microsoft.com/ja-jp/services/blockchain-service/)は、Microsoft Azureが提供するフルマネージドのブロックチェーンサービスです。ゼロからブロックチェーンアプリケーションを作る場合には、ネットワークの展開や鍵管理の仕組みなどは全て手作業で構築することになりますが、これは大変な作業です。Azure Blockchain Service(略称: ABS)を用いることで、面倒な作業を全てAzureにお任せし、ユーザーはボタン操作だけでブロックチェーンネットワークを構築することができます。

本記事では、実際の作業手順よりも読者の皆様の**イメージ作り**をメインの目的とします。そのため、全ての機能はご紹介しません(詳細を把握されたい方は、[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/blockchain/service/)をご参照ください)。**「Azure Blockchain Service使うとこんなことができるんだな～」**とザックリご想像して頂けたら幸いです！

#ABSでできること1: ブロックチェーンネットワークの展開とコントラクトの実行
##1.1 まずは、Azureポータルから作成
ABSは他のAzureサービスと同様に、皆さんお馴染みのAzureポータルから作成できます。
(もちろんAzure CLIもご利用可能です)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/e4a602c1-e998-89af-eed6-3138b953f541.png)

作成画面は下記のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/1c7dccc4-a13e-e43e-0030-f694330443a5.png)

いくつか必須入力項目がありますが、以下の構成概略図をイメージすると分かりやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/e4f5b8ee-0f58-e804-8923-23caa1260b99.png)

**★詳細** 

* 99.9%のSLAを提供しています(Standard SKU)。これには、ノードのリカバリーと台帳のバックアップが含まれます。 
* コンソーシアムに参加する人や企業は “Member” として扱われます。
* 各Memberごとに、”Transaction Node” と “Validator Node”を持ちます。Transaction Nodeは最大10個まで、Validator Nodeは最大2個まで(Standard SKU)作成することができます。
* 台帳およびログの容量が増えた場合、ノードのストレージは内部で自動的に増えます。


各項目ごとに任意の値を入力し数分待つと、展開が完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/041f9473-269e-883d-e92f-1c901e10fe63.png)

##1.2 Visual Studio Codeでスマートコントラクトを作成&ABSにデプロイ
簡単なGUI操作でブロックチェーンネットワークを構築できましたね！続いては、スマートコントラクトをローカル環境で作成し、ABSにデプロイしてみたいと思います。デプロイができたら、Gethを使って呼び出してみます。イメージはこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/73e8fcd4-5a7b-eff0-11bf-4cbdda997397.png)


事前準備として、Visual Studio Codeに[Azure Blockchain Development Kit for Ethereum 拡張機能](https://marketplace.visualstudio.com/items?itemName=AzBlockchain.azure-blockchain)を入れておくことをおすすめします。スマートコントラクトの開発や展開、操作などを楽にしてくれます。
(その他の環境構築方法に関しては、本記事では省略します)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/3b476021-ff6d-9b69-0deb-40d532a84b64.png)

VS Code上でF1を押し、Azure Blockchain: New Solidity Projectを選択しフォルダーを指定すると、画面左部のように階層構造とテンプレートファイルを作成してくれます(≒ truffle init)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/736b5c2b-8592-e633-44a4-2b8753004f08.png)

テンプレートとして作成されたHelloBlockchain.solを検証用に下記のソースコードに書き換えます。

```solidity:simpleStorage.sol
pragma solidity >=0.5.0 <0.6.5;

contract simpleStorage{
    uint public storedData;

    function simplestorage(uint initVal) public{
        storedData = initVal;
    }

    function set(uint x) public{
        storedData = x;
    }

    function get() public view returns (uint retVal){
        return storedData;
    }
}
```

書き換えられたらコントラクトのビルド後、ABSにこのコントラクトをデプロイします。ビルド及びデプロイは、.solファイルを右クリックするとメニューとして表示されるのでクリックするだけです！デプロイ先のABSも接続を行うと画面上部に表示されるので、あとはクリックすると展開されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/4ff486e9-8c65-f7d2-5302-a53b06e75fb2.png)


デプロイが成功したら、Contract Interaction Pageで動作を確かめてみます。UIが自動生成されてVS Code上ですぐに動作確認できるのは便利ですね。
(Contract Interaction Pageも.solファイルを右クリックすることでメニューから起動できます)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/a017533f-273e-7dfb-e113-8a1faa627198.png)

##1.3 Gethでトランザクションノードに接続し、コントラクトを実行
無事にコントラクトがデプロイできましたね！それでは最後に、GethでABSのトランザクションノードに接続したいと思います。トランザクションノードの接続情報(HTTPS+Access Key)は、Azureポータルで確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/05ca580d-4849-91c6-62bb-359b03a5fa1e.png)

ローカル環境から、ABS上のGethインスタンスに接続をします。BytecodeやABIは、先ほど利用したContract Interaction Pageで確認できます。値をセットし、ゲットできました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/85db6bd1-a78f-a41d-d428-42fd5b0705b9.png)

**★ちょこっとTips**
ABSに対して操作をする場合に、上図のように「Error: authentiaction needed: password or unlock」と表示される場合があります。これは、ABSが外部からのアクセスをロックしているため表示されるエラーメッセージです。ロックを一定時間解除するには、下記コマンドを実行する必要があります。
(Azure CloudShellを利用すると便利です！)

```
curl -X POST -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method":"personal_unlockAccount","params":["メンバーアカウントアドレス", "メンバーアカウントのパスワード", 秒数],"id":1}' "https://メンバー名.blockchain.azure.com:3200/アクセスキー"
```

#ABSでできること2: コンソーシアムネットワークの管理&構成
次はこのような構成を作り、検証してみます。実際のユースケースでは、このように複数のステークホルダーとコンソーシアムを組んでデータを共有する形になるかと思います。ABSではどのようにコンソーシアムを作り、どのようにデータが共有されるのか確認してみましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/1f7e9093-f3df-b9a3-7c5d-158fc30815f3.png)

##2.1 コンソーシアムメンバーの招待
セクション1の構成では作成したコンソーシアム(taminaabstestconso)に1つのメンバー(member001)しか参加していませんでした。このコンソーシアムに、member002とmember003を招待したいと思います。
(ここでいうメンバーは、データを共有する協業他社やパートナー企業を想像してみてください。)

招待の方法は現在PowerShellを利用した方法のみサポートしており、[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/blockchain/service/manage-consortium-powershell)に手順が記載されています。一見面倒そうな手順やコマンドレットが書かれていますが、要約すると、**ABSにおいてのコンソーシアムメンバーの招待は、Azureサブスクリプション単位で行います**。例えば、自分達の企業Aとコンソーシアムを組むことになった企業Bを招待する場合、企業BのAzureサブスクリプションIDさえ分かれば招待することができます。

実際に招待を受け取ると、ABSの作成画面に、招待されたコンソーシアム名が表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/12c5494e-4929-0928-4ff4-42cbb2f30537.png)

Azureポータルで、コンソーシアムの情報を確認することができます。1つのコンソーシアムに3社が加盟しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/be79e4c0-2712-3818-ac0d-35f30e25f052.png)


##2.2 ブロックチェーンが同期されているかを確認
コンソーシアムネットワークを構築することができました！しかし、コンソーシアムを組んだだけでは意味がありません。コンソーシアムを組んだメンバー同士は、お互いが持つデータを全て共有した形になっていなければ意味がありません。コントラクトおよびデータが後から参加したメンバーにも共有されているのかどうか、確かめてみましょう。

セクション1.3で設定した変数test1を利用して、コントラクトアドレスを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/41d21a3a-62a1-5a89-58f8-cfd75cf8fce7.png)

このコントラクトアドレスを元に、先ほどmember001が格納した数値(11でしたね！)がコンソーシアムを組んだ他のメンバーからも閲覧できるかどうか確かめてみます。

**◎member002から取得した結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/aac8d8cd-ef6e-f658-8e0a-8b7cf83d00f8.png)

**◎member003から取得した結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/d79f14b6-4c32-1b4e-217c-24e445faf3e3.png)

member001が入力した情報を、member002もmember003も見ることができました！Azureポータル上のメトリックビューでもトランザクションの同期を確認できます。
(※member003は一番最後に追加したのでトランザクション数が一つ少ないです。)

**◎member001のメトリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/ed84146f-3357-f815-b6e6-f295b75b59c4.png)

**◎member002のメトリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/ca647e8c-dd43-3143-3d27-2b683b7b18c2.png)

**◎member003のメトリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/606c24f8-68e1-e12d-c6d9-9577b1f8228b.png)


**コンソーシアムに参加すると、裏側でブロックチェーンを自動的に同期してくれる**ことが分かりましたね！

**★ちょこっとTips**
Azure Blockchain Serviceは現在、QuorumのIBFTコンセンサスアルゴリズムを採用しています。IBFTでは、トランザクションがなくてもブロックが一定の間隔で作成されていきます。geth attachをした際に表示されるat blockというパラメータで、実行時によってブロック数が異なる(増えている)のはそのためです。


#ABSでできること3: プライベートトランザクション
ネットワークに参加している全てのメンバーでデータを共有できるというのがブロックチェーンの一つの特徴であり、ブロックチェーンを採用する理由の一つでもあるかと思いますが、エンタープライズのユースケースだとこれが不都合になる場合があります。例えば、**ある限られた取引情報だけは特定のメンバーに見せたくない**という要件が出てくる場合があります。Azure Blockchain Serviceで採用されているQuorumでは、プライベートトランザクションという機能を使って、そのような要件を満たすことができます。

このセクションでは、下記のようなことが実現できるのかどうか検証してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/6dd5f69c-0678-b993-5721-7b7c352b53fe.png)

##3.1 プライベートコントラクトの作成
特定のメンバーのみがアクセス可能なコントラクトであるプライベートコントラクトをまずはデプロイする必要があります。デプロイスクリプト内に**privateFor**要素を追加することで、どのメンバーに対して有効なコントラクトなのかを指定できます。今回の例では、**privateFor["member001の公開鍵","member002の公開鍵"]**という形式になっています。

```javascript:2_deploy_contracts.js
var simpleStorage = artifacts.require("simpleStorage");
var Arg = 24;

module.exports = function deployContracts(deployer){
    deployer.deploy(simpleStorage, Arg, {
        privateFor: ["I1xsruEPUdC5JBEgr2wso4VORNhlzzlXAsCTDh0U51A=","D2e3q38dEcjDjVxh6tdhQzzzknSPGqcryyBzgC/+rV8="]
    });
};
```

各メンバーが持つTransaction Nodeの公開鍵は、Azureポータルで確認できるので、コピペするだけです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/7693392e-56c5-c785-1390-bf51bd82897b.png)

##3.2 プライベートトランザクションの作成
プライベートコントラクトがABSにデプロイできたら、早速プライベートトランザクションを発行して動作確認をしてみましょう。

**◎まずはmember001に接続**
privateForを使って、member001とmember002を共有範囲として指定しています。22という値が0x9f0d...というアドレスに格納されましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/95e7bdaa-24fe-f4f9-fe9c-b1253e7ff1f7.png)

※ABSのアンロックを忘れずに！

**◎member002に接続**
member002から接続をし、コントラクトアドレスを元に値を確認してみます。member001から共有された22が取得できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/61f04c24-5199-7153-bb0c-a0b30f536f08.png)

**◎member003に接続**
member003から接続をし、コントラクトアドレスを元に値を確認してみます。member001から共有された22が取得できず0と表示されましたね。仮説検証ができました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/edf94947-6719-29de-df73-110fe2bd9193.png)

メトリックビューでも確認してみましょう。member003には、001と002で行われたトランザクションの中身は見えないものの、トランザクションが発行されたという情報は共有されているようです。
**◎member001のメトリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/bc5089d1-70eb-adfa-1736-2d147e1ad8cf.png)

**◎member002のメトリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/4ff99305-c9a5-fefe-60f2-6aa976c07e2f.png)

**◎member003のメトリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/ad44c132-3ecf-3525-5912-9b347ba6ff4f.png)

**★ちょこっとTips**
Quorum上でプライベートトランザクションを管理してくれる機能をトランザクションマネージャーと呼んでいます。トランザクションマネージャーとしては、haskellで開発されている「Constellation」と、Javaで開発されている「Tessera」があります。Azure Blockchain Serviceでは現在、Tesseraトランザクションマネージャーを採用しています。
https://docs.microsoft.com/ja-jp/azure/blockchain/service/ledger-versions

##3.3 複数台トランザクションノードを立てた場合のプライベートトランザクション (おまけ)
ABSでは各メンバーごとに最大10台までトランザクションノードを持つことができます。トランザクションノードを複数台立てたときにも、セクション3.2で検証したようなことができるのかどうか試してみます。イメージはこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/6ba2385e-f224-3645-5375-bce1aa4c9be8.png)

**◎まずはmember001に接続**
privateForを使って、member001のDefault Nodeとmember002の2つのトランザクションノードを共有範囲として指定しています。33という値が0x2d5d...というアドレスに格納されましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/e0bdca80-197f-1da4-6b5a-b033bb42b075.png)

**◎member002の2つめのトランザクションノードに接続**
member002の2つめのトランザクションノードから接続をし、コントラクトアドレスを元に値を確認してみます。member001から共有された33が取得できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/6cf8a4ca-81ef-d25a-b064-5e6659cf83e9.png)

**◎member001の2つめのトランザクションノードに接続**
member001の2つめのトランザクションノードから接続をし、コントラクトアドレスを元に値を確認してみます。member001のDefault Nodeから共有された33が取得できず0と表示されましたね。仮説検証ができました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267543/18976b04-7258-a83e-81a5-f73029d0af75.png)

結論として、同じメンバー内でもプライベートトランザクションを作成することができることが分かりました。

#さいごに
少しDeep Diveしたところもありましたが、いかがでしたでしょうか？機能はこの記事でご紹介したもの以外にも沢山ありますが、特徴的なものを実際に触りながら試してみました。Azure Blockchain Serviceを使ってできることを何となくでもよいのでイメージして頂けておりましたら幸いです！

#主に参考にした文献
[Go HayakawaさんのQiita](https://qiita.com/hayago): とても分かりやすくまとまっており、本記事作成にあたっても大変お世話になりました。
[Matsuzakiさんのブログ](https://tsmatz.wordpress.com/2019/11/06/azure-blockchain-service-quorum-tutorial-web3-truffle-develop/): 詳細を学習することができ、素晴らしい内容です。ありがとうございます。