Azure Blockchain WorkbenchのREST APIを活用して（モバイル）アプリを開発する

#Azure Blockchain Workbenchとは
AzureにAzure Blockchain Service(以下ABS)とAzure Blockchain Workbench(以下ABW)がある。
ABWはブロックチェーンを展開しやすくしたプラットフォームである。裏でABSを使っている。
ABWの概要について公式のドキュメント：『[Azure Blockchain Workbench とは](https://docs.microsoft.com/ja-jp/azure/blockchain/workbench/overview)』を参照。

##目標
デジタル改革時代において、あらゆる分野でのブロックチェーンの期待が高まっている。
金融期間だけではなくサプライチェーンやIoTでも活用シーンが増えている。
ABWはブロックチェーン技術の多様化の可能性を広げる。
ABWのREST APIを使用すれば、UIの開発とブロックチェーンの開発を分散できる。
本書でAzure FunctionsからABWのREST APIの使用方法とサンプルを提供し、多様化・活用の拡大を目指す。

##前提条件
対象者：レベル300以上
下記のソフトは事前にインストールしていることを前提とする
1.Postman
2.Visual Studio(VSCode)
3.DOTNET Core SDK and Azure Functions SDK
他にC#とSQLサーバーのスキルが必要。

##事前準備
まず、下記リンクの手順に従ってABWを（Azure AD 構成部分まで）デプロイする。
<font color="red">**重要**</font>：デプロイするリージョンは手順書通り『米国東部』にしてください。日本リージョンにデプロイすると利用料金が高くなる。
[ABWのデプロイ手順書](https://docs.microsoft.com/ja-jp/azure/blockchain/workbench/deploy)
<font color="Red">設定したユーザーIDやパスワードを忘れないように控えておく。</font>
この時点でAzure ADにABWのAPI用のアプリケーションが作成されているはず。

ABWの[サンプル](https://github.com/Azure-Samples/blockchain)をダウンロードして、Asset Transferアプリケーションを追加する。
ローカルフォルダのパスを追って、JSONとSOLを順番にデプロイする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/ee9f6638-bdfe-0631-cfab-41337de2a587.png)
アプリケーションをクリックして、Ownerロールのユーザーを追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/1481dee9-d6df-dbe3-3a5b-1833fee99113.png)




##REST API用のアプリケーションをAzure ADに登録する
１．新規のエンタープライズアプリケーションを作成
Azureポータル→メニュー→Azure Active Directory→エンタープライズアプリケーション→新規アプリケーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/2b307e1f-779c-324c-fefe-f4e3d6aaa2db.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/0b0e663f-1bbe-be59-ed5a-a395b6550311.png)
２．APIキーの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/d4ad2b51-4560-67af-a590-986ddf25d642.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/ff04cbca-7a75-08fb-f5d0-827dceccbc11.png)
<font color="red">**重要**</font>：必ずコピーボタンを押して、作成したキーの値をメモ帳などに保存する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/29d53427-a60e-e298-713d-b8bf536734f9.png)

3.作成したアプリケーションのIDを取得してメモ帳などに保存する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/585c049c-8700-465b-d9bc-edcb61f720f1.png)

4.アクセス権限を付与する。
自分のAPIから上記の事前準備で作成されたABWのアプリケーションAPIを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/63041972-d753-c1e0-81d9-ab1c739d1b2b.png)
ABWのアプリケーションAPIが存在しない場合、上記の事前準備からやり直す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/094d90b3-b347-729f-c349-d50d5af2a048.png)
今回はアドミニストレータ権限を付与するので同意が必要。
**注意事項**：プロダクション（本番）環境は必要最低限の権限を付与する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/9d6bac42-a294-39f2-9a5c-1f179bdd28be.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/349773b8-0f1a-d8a2-569e-06fa99423b21.png)
5.ユーザーIDを取得
全て上手くいけば、事前準備で作成されたABWのアプリケーションAPIのユーザーに上記で作成したアプリケーションが追加されているはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/153def2c-23fb-4a59-facd-4fa5a9f0cf7f.png)
アプリケーションをクリックしてブラウザのURLからユーザIDを取得してメモ帳などに保存する。
ユーザーIDはこんな感じ：XXf2731e-0ecf-484b-abdf-9151e3212999
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/1bd30043-87ed-b48e-f925-25ac14849fbb.png)


##REST API用のユーザーをABWに登録する
このセクションは少しトリッキーであるため、
まず、Microsoft公式ドキュメント：
1.[ブロックチェーンアプリを使用する](https://docs.microsoft.com/ja-jp/azure/blockchain/workbench/use)
2.[Workbench ユーザを管理する](https://docs.microsoft.com/ja-jp/azure/blockchain/workbench/manage-users)
3.[Workbench APIを使用する](https://docs.microsoft.com/ja-jp/azure/blockchain/workbench/use-api)
を一読する。

さて、APIユーザーを作りましょう。
1.[postmanコレクション](https://github.com/Azure-Samples/blockchain/tree/master/blockchain-workbench/rest-api-samples/postman)をダウンロードしてpostmanにインポートする。
2.設定を変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/aa8a3e4b-b6b5-1097-aa23-9d3842df6df6.png)
変更必要な箇所は：
・Pre-request Scripts
・Variables
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/2987f96a-15d0-f002-cfbd-007d48321406.png)
まずはPre-request Scriptsの
①Azure ADのテナント
②上記事前準備で作成されたアプリケーションID
③上記で作成したREST API用アプリケーションID（メモ帳に保存しているはず）
④上記で作成したREST APIキー（メモ帳に保存しているはず）

```javascript:code
const echoPostRequest = { 
  method: 'POST',
  url: 'https://login.microsoftonline.com/①.onmicrosoft.com/oauth2/token',
  headers: 
  { 
    'cache-control': 'no-cache',
    'Content-Type': 'application/x-www-form-urlencoded' 
  },
  body: 
  {
    mode: 'urlencoded',
    urlencoded: 
    [
        {key: "resource", value: "②", disabled: false},
        {key: "client_id", value: "③", disabled: false},
        {key: "client_secret", value: "④", disabled :false},
        {key: "grant_type", value: "client_credentials", disabled: false}
    ]
  }
};

pm.sendRequest(echoPostRequest, function (err, res) {
    console.log(err ? err : res.json());
        if (err === null) {
            console.log('Saving the token and expiry date')
            var responseJson = res.json();
            pm.environment.set('currentAccessToken', responseJson.access_token)
        }
    });
```
次にゴローバル変数を定義する。
baseURLは基本URLに-apiがついているものとなる。
URLの取得は上記の「3.Workbench APIを使用する」を参照。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/12248648-23b4-ea41-8c18-cf67eab657e4.png)
Updateしてダイアログを閉じる。

3.ユーザ作成APIを呼び出す。
まず、設定を確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/8fd171d5-a1e0-1b35-87cf-bb2c33e141c9.png)
次にパラメータを設定する。
externalIDに上記で取得したユーザIDを設定する。
あとは任意の値を入力する。
Sendボタンを押してユーザを作成する。
上手くいけば結果が200で、作成したユーザーのID(一桁の数値)が返ってくる。
このユーザIDを覚えておく必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/10e483b7-b25b-1c9b-972f-6f66e737cc8b.png)

4.ここがトリッキーな部分
ABWのユーザーはAzure ADで管理されているので、上記で作成したユーザはAzure ADに存在しないため、
アプリケーションのメンバーとして追加することができない。
右上のmemberをクリックすれば確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/16f9b031-d12d-066b-5c9a-3b5091135efe.png)

Azureポータル→ABWのリソースグループ→ABWのデータベース（アイコンい歯車がない方）→サーバファイアウォール設定でクライアントIPを追加して、SSMSからアクセスできるようにする。
SSMSを立ち上げて、下記の通り１レコードを追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/fe5b8c33-f171-062e-1321-5f60f88dc460.png)
RoleAssignmentテーブルを編集モードで開いて、
上記で追加したAPI用ユーザIDとApplicationRoleIdを入力する。
ApplicationRoleIdの値はすでにあるレコードと同じ値を入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/35849f91-5c6b-4b46-2a92-2b425aa6e532.png)
最後にアプリケーションのメンバーシップを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/29395492-d4ca-c319-9572-38ac3ac5dbf4.png)


##Azure Functionsを使ってアセットを登録しましょう
ソースコードを[github](https://github.com/mesgar/ABWFunction)からダウンロードして、Visual Studio 2019で開いて、認証情報を設定する。
設定する内容は上記postmanの設定と同様である。

```csharp:コード
// 上記事前準備で作成されたアプリケーションID
static string APPLICATION_ID = "";
// APIのURL
static string API_URL = "https://xxxxxxx-api.azurewebsites.net";
// Azure ADのテナント
var AUTHORITY = "xxxxxx.onmicrosoft.com";
// 上記で作成したREST API用アプリケーションID（メモ帳に保存しているはず）
var CLIENT_ID = "";
// 上記で作成したREST APIキー（メモ帳に保存しているはず）
var CLIENT_SECRET = "";
```

<font color="Red">1回目実行すると新規のユーザー（現在のユーザー）が作成される</font>

```csharp:コード
// 96行目の結果は１回目はfalseで、２回目以降はtrueになる
var canUserAccessWorkbench = await GatewayApi.Instance.CanCurrentUserCreateContractsForWorkflow(WORKFLOW_ID);

```

```csharp:コード
// １３０行目にアセット情報を設定する。
workflowAction.WorkflowActionParameters.Add(new WorkflowActionParameter() { Name = "description", Value = "Computer" });
workflowAction.WorkflowActionParameters.Add(new WorkflowActionParameter() { Name = "price", Value = "999" });

```
F5を押してプロジェクトを実行する。
アウトプットウインドからURLを取得してブラウザでURLを開く。
すべて上手くいくと下記のようにアセットが登録される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/2e22ffd3-6737-f1b5-b238-b10adda8351d.png)

**Happy chaining**

[参考記事:mahdi alirezaie Jan 12, 2019](https://medium.com/@malirezaie/how-to-enable-programmatic-interaction-with-azure-blockchain-workbench-apis-56c0d95c79c0)