ブロックチェーンでリモート承認を導入してみる

新型コロナウィルスの影響でリモートワークの検討をしている人も多いかと思います。
NEMのCatapultエンジンを搭載したブロックチェーンでリモート承認に挑戦してみましょう。

３話完結です。
[ブロックチェーンでリモート承認してみる（２）](https://qiita.com/nem_takanobu/items/98bef1490f7e10c4ceac)
[ブロックチェーンでリモート承認してみる（３）](https://qiita.com/nem_takanobu/items/fe5e1f321e2641ff918a)

大まかな処理の流れは図の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/1672fa61-58f7-d53d-40cd-aeeb2e988b4e.png)

- 申請者が申請ファイルのハッシュ値を取得
- ブロックチェーンにファイルハッシュ値を登録
- 承認者にファイルとトランザクションハッシュ値を通知
- 承認者はファイルのハッシュ値とブロックチェーンに刻まれたファイルハッシュ値を照合し、申請者による依頼であることを確認
- 承認者は申請トランザクションに対し承認
- 承認者が申請者に承認トランザクションハッシュ値を通知
- 申請者はトランザクションハッシュ値から承認者による承認であることを確認


では今回もchromeブラウザで動作確認していきましょう。
F12キーあるいは fn+F12キーを押してデベロッパーツールを開きます。

### 事前準備

symbol-sdkを読み込みます。

```js
(script = document.createElement('script')).src = 'https://xembook.github.io/nem2-browserify/symbol-sdk-pack-0.21.0.js';
document.getElementsByTagName('head')[0].appendChild(script);
```

各クラスや変数の宣言を行います。

```js
nem = require("/node_modules/symbol-sdk");
NODE = "https://sym-test.opening-line.jp:3001";
GENERATION_HASH = "6C1B92391CCB41C96478471C2634C111D9E989DECD66130C0430B5B8D20117CD";

txHttp = new nem.TransactionHttp(NODE);
accountHttp = new nem.AccountHttp(NODE);
```

申請者（alice）と承認者(bob)アカウントを生成し、フォーセットから手数料分を入金しておきます。

```js
alice = nem.Account.generateNewAccount(nem.NetworkType.TEST_NET);
"http://faucet-0.10.0.x-01.symboldev.network/?recipient=" + alice.address.address +"&amount=10"

bob = nem.Account.generateNewAccount(nem.NetworkType.TEST_NET);
"http://faucet-0.10.0.x-01.symboldev.network/?recipient=" + bob.address.address +"&amount=10"
```

アカウントが生成されると、フォーセットへのリンクが出力されます。クリックしてページを開き、`CLAIM!` ボタンをクリックすると、10XYM送金されます。
残高が増えたか確認しておきましょう。

```js
accountHttp.getAccountInfo(alice.address).subscribe(x=>console.log(x.mosaics[0].amount));
accountHttp.getAccountInfo(bob.address).subscribe(x=>console.log(x.mosaics[0].amount));
```
エラーが出る場合はまだ入金が完了していません。
入金が完了すると以下のように表示されます。

> UInt64 {lower: 10000000, higher: 0}


### 申請
コマンドプロンプトより申請ファイルのハッシュ値（要約値：デジタル指紋）を取得します。

```shell
> CertUtil -hashfile C:\Users\application.txt SHA256
```

>SHA256 ハッシュ (対象 C:\Users\application.html):
b7d3e3191d2d2e77ed6e455eeaec147c13e19f0c079f0ca0dcff853f3df46911
CertUtil: -hashfile コマンドは正常に完了しました。

上記コマンドで出力された文字列をメッセージに指定して申請します。

```js
tx = nem.TransferTransaction.create(
    nem.Deadline.create(),
    bob.address,
    [],
    nem.PlainMessage.create('b7d3e3191d2d2e77ed6e455eeaec147c13e19f0c079f0ca0dcff853f3df46911'),
    nem.NetworkType.TEST_NET,
    nem.UInt64.fromUint(100000)
);
signedTx = alice.sign(tx,GENERATION_HASH);
txHttp.announce(signedTx).subscribe(_ => console.log(_), err => console.error(err));
"https://sym-test.opening-line.jp:3001/transactionStatus/" + signedTx.hash

```


### 署名

申請者から送られてきたファイルのハッシュ値を確認します。

```
> CertUtil -hashfile C:\Users\application.txt SHA256

SHA256 ハッシュ (対象 C:\Users\application.html):
b7d3e3191d2d2e77ed6e455eeaec147c13e19f0c079f0ca0dcff853f3df46911
CertUtil: -hashfile コマンドは正常に完了しました。
```

ブロックチェーン上のハッシュ値とメッセージを確認します。

```js
accountHttp.getAccountTransactions(bob.address).subscribe(x=>console.log(x[0].transactionInfo.hash));
accountHttp.getAccountTransactions(bob.address).subscribe(x=>console.log(x[0].message));
```


メッセージに承認を刻んでトランザクションを発生させます。

```js
tx = nem.TransferTransaction.create(
    nem.Deadline.create(),
    alice.address,
    [],
    nem.PlainMessage.create('approved'),
    nem.NetworkType.TEST_NET,
    nem.UInt64.fromUint(100000)
);
signedTx = bob.sign(tx,GENERATION_HASH);
txHttp.announce(signedTx).subscribe(_ => console.log(_), err => console.error(err));
```

### 確認

alice（申請者）の最新のトランザクション履歴を見てみましょう。

```js
accountHttp.getAccountTransactions(bob.address).subscribe(x=>console.log(x[0].signer.address));
accountHttp.getAccountTransactions(bob.address).subscribe(x=>console.log(x[0].message));
```

承認者のアドレスを確認します。
メッセージが `approved` であることを確認します。

これで承認のフローを確認することができました。
また随時追記していきます。