Dappを作ってアプリケーションの側面からブロックチェーンのメリットを考えてみた

初投稿で読み辛い点＆独学の知識なので誤ってる点が多々あるぽいですが書くなら今と思い立って
ソフバンやマスタカードが既に似た仕組み作ってるし、会社で知財の判定待ってたら誰かが先にローンチしちゃうだろうし

---
#はじめに

何かと話題のブロックチェーンですが個人と企業で流れてくるネタが食い違ってますよね？

- 個人
	- 「この仮想通貨なら儲かる！」
	- 「××（飲食店など）で仮想通貨の決済開始」
	- 「ハッキングを受けにくいウォレット保管」
- 企業
	- 「食料品サプライチェーンの実装実験」
	- 「ドキュメントの改ざん対策」
	- 「フィンテックの大本命」

日本企業の40%がブロックチェーンに取り組んでいるという記事もありました。
何を取り組んでいるのか知るべくDapp作ってICOごっこ(???)してみました。

#ホワイトペーパーの問題提起と解決策的な

個人的にパスワード管理はExcel課題管理表、全社共通ファイルサーバーと同レベルの悪だとは思っていません。

というのも今もてはやされている生体認証は、結局は生体特徴量をデータ化したものになるので
生体情報プラス行動情報(現在位置とか)を合わせたものにしないとDeep LearningのGANみたいなのが
特徴量を再現させてしまうリスクがあると考えています。
そうなるとタヒぬまで同じ認証は怖いですよね。人差し指から一本ずつ認証に使える指が無くなっていくという。笑

パスワード管理であれば適切な運用であれば突破はそこそこ難しく、小学生レベルでも運用概念を理解し、
不正利用されたらリセットして管理権限を取り戻せるでしょう。

あくまでパスワード管理は手法自体が人力の記憶まかせになっているところで忘却したり、
盗まれたりするポイントが一番の綻びポイントと思い、
パスワード管理自体をシステムに任せることで問題点を解消できると考えました。

---
#つくったもの

<img width="202" alt="login.png" src="https://qiita-image-store.s3.amazonaws.com/0/189193/f1f99a38-ea6e-16e3-02aa-208f8d4a75a3.png">
こういう、よくあるサインアップ／ログイン画面で

<img width="273" alt="menu.png" src="https://qiita-image-store.s3.amazonaws.com/0/189193/8f4d4115-b038-db27-3935-4a7e525130f5.png">
IDと自動生成したパスワードをEthereum上に記録し、そのID情報でバックグラウンドでサインアップして

<img width="283" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/189193/e7141e2a-7c66-d529-4bcd-d8664fea1951.png">
該当サイトを開いた時にDappに記憶したHTMLの要素と対になったアカウント情報を流し込むシステムです。

<img width="173" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/189193/8b74fc87-ce8e-9e65-22b5-15718009a34e.png">

- [Metamask]
	- ユーザーはMetamaskのウォレットをUnlockすることでアカウントアドレスに紐づいた認証としています。
	- ID情報をDappに記録したり、更新したりするETHはここから支払います。
- [HTML+Web3.js]
	- ポータル画面のように使います。ボタン押してID作成と、サイトを開いてIDを流し込みが出来ます。
- [Truffle]
	- Dappをデプロイするなど開発環境に使用しました。
- [Geth]
	- Ganacheは何故かMetamaskでアカウントのインポートがうまくいかなかったのでGethを使いました。

ここではTruffle開発環境の構築方法は他のもエントリーが色々あるので割愛します。

余談ですが2年くらい前にSolidityを触った時はコードをすべく一行にまとめてGethに流すという苦行があり、
トライ・アンド・エラーしか出来ないジブンはあれで開発する気が無くなったもんですが随分変わりましたねー。

---
#こんなメリットが

- ネットワーク全滅しない
	- Ethereumが停止するなんて起きないですよね。万一ハッシュレートがだだ下がりなんて起きたら51%問題起こされないように大量のトークン保管者がトークンを売ってASIC買ってマイニングしたりして
- 基盤運用要らない
	- クラウドサービスだと結局リージョン分けて冗長化して・・みたいな観点がどうしても出てくるけどIaaSと違って全世界でマイニングされているサーバーが受け皿になるから監視すらなく、アプリをデプロイすれば終わり。
	- Web画面の部分はデータを記録しないのでサーバーレスアーキテクチャーで問題ないです。

---
#いや、それDapp共通のメリットじゃね？

であれば考え方を変えて、プライベートチェーンで動かすとしましょう。
ID情報を取得する処理もトランザクションとして残せば情シスお助け要素が出てきます。

 - 管理業務が無くなる
	- パスワードが何かを意識しなくて良いので、パスワードが何かを意識することは無くなる。なのでパスワード忘れた、からのリセット運用が無いし。更新ボタンも用意してあげれば定期的な更新にも対応できる。
 - リソースの実使用を可視化できる
	- 外部SaaSへ使っていない人がいたり、実際にはヘビーに使っているのに部署が変わって利用停止みたいなあるあるを回避。誰がどのサービスを何時使ったのかその時のパスワードは何かまで可視化できる。
 - 統合的にアクセスロールが適用できる
	- ログインする管理画面から飛んでも認証されないのであれば該当SaaSへのアクセスロールが無いという事になる。情シス側で払い出したいユーザーだけ選んでIDを生成すれば良くて、それはアクセスロール同様に扱える。

---
#まとめ

スマートコントラクトはただのKVSのようでアイディアひねってみるとIoTみたくデータ活用の要素がふんだんにあり、
出回っているカジノやゲームに限らず企業が研究する興味深いものになっている事を学ぶことができた。
なので企業はブロックチェーン技術自体に注目する流れは仮想通貨が衰退しても変わることはないでしょう。

今後Raiden Networkやシャーデングでスケーリングが解消されていくと、企業の受け付けWeb画面みたいなものは
コスト的にもDappの方が強く、クラウドサービスを侵食していく可能性もあるかと思う。
クラウドかブロックチェーンのどちらにLift and Shiftします？なんて世界も来るかもしれないですね。

---
#これだけだとただのポエムだけなので今回のハマりポイントも書いておきます

##ABIの更新や、Dappのデプロイアドレスに注意

Truffleの/(プロジェクト名)/build/contractsの下に(Dapp名).jsonがあって中にコントラクトのアドレスや
ABIがかかれている。ABIはDappの関数情報のようなもので、これをweb3.jsからも読み込むようにするのですが
うっかり関数を更新したのにABIを変え忘れると動かない。このABIの切り出し作業は結構手間です。

あとコントラクトのアドレスは

```
  "networks": {
    "11": {
      "events": {},
      "links": {},
      "address": "0x3e13eb1d8244e7b90ff9edc367e03bcf9710a98b",
      "transactionHash": "0x24a4e62380f786ebfcd48c1c85fae00c921ac14db19d11dc8147e3c2d5d89df2"
    },
```

みたいに何個か書かれているのですがnetwork_idと一致しないみたいでどれがアドレスかぱっと分からない。

```
 Replacing PasswordKvs...
  ... 0x677e5d21bd6b68d8d9fcf63706bac6b5760f891c0785d561626a1e9888dad6e4
  PasswordKvs: 0x19d3d841bae78110867f1f10131ac1b0112c9d93
```

Truffleからmigrateする時に出るアドレスを控える方が良いです。

##GAS不足でsendTransactionしてETHが減るも更新されない

```
contract.StringSet(A, B, C, D);
```

こんな感じで長いstringを複数個Dappに入れるときにsendTransactionには成功するものの、
ETHが減ってもデータが更新されない事があります。その場合は


```
web3.eth.getTransaction("0x2440e534f5551e83a2528869f147332d97210b3403f4554aa98a1dab5af6f80d")
```

このようにsendTransactionを覗いてあげるとGASが足りていないのが分かるので

```
contract.StringSet(A, B, C, D', {from: res, gas: XXXXXXXXX});
```

関数自体にGAS量を指定してあげれば反映されるようになります。
ちゃんと理解していないですがこの動作はTruffleのmigrations配下のデプロイする
Javascriptの中にGASを指定することや

```
var PasswordKvs = artifacts.require("./PasswordKvs.sol");

module.exports = function(deployer) {
  deployer.deploy(PasswordKvs, {gas: XXXXXXXXX});
};
```

Truffle自体の設定ファイルにgas書いてあげると解消できそうです。
ちなみにTruffleの設定ファイルはganacheだとtruffle-config.jsに設定を書き、
gethを使う場合はtruffle.jsに書くとのこと。

```
module.exports = {
  networks: {
    live: {
      host: "localhost",
      port: 8545,
      network_id: "13",
      gas: XXXXXXXXX
    }
  }
};
```

**ていうか、反映出来ないかつGAS足りてないなら返金してください。。**

##Unlockされる

参照でなく、sendTransactionする関数を実施する場合は都度Unlockする必要がありました。
自前の古いPC＋GPUではハッシュレートが低いせいなのかUnlockして、Unlockされた事を
待ってあげてからsendTransactionしないとDappのデータが更新できませんでした。

##文字のコンカチ、比較や変数の型変換とかプログラミング言語では通常用意されている命令が無い

Solidityが最低限動く実装になってようなので文字操作みたいなユーティリティな命令がありません。
無ければ出来ないという訳では無いのでstackoverflowあたりから探してくる必要があります。
もち有志がアップしている関数ってだけなので動く保証はありません。追加デバックする必要も出てきます。