NEMブロックチェーンを利用したアプリケーションを開発するためには

こんにちは。

NEMを使ったアプリケーションを開発している[shohei](https://twitter.com/hobbydevelop)です。

Advent Calendar初投稿ですよろしくお願いします。

NEMを使ったら簡単にアプリが作れるっと聞いたことがあると思いますが、じゃあ具体的にどうやって作るの？何が必要なの？というところを私の知見を含めて紹介したいと思います。

## そもそも何でNEMを使ったら簡単って言えるのか？
NEMの機能をWebAPIとして提供しているからです。
例えば残高取得するためには以下のWebAPIをブラウザでアクセスすると残高情報を[JSON形式](https://dev.classmethod.jp/etc/concrete-example-of-json/)で取得することができます。

[https://aqualife2.supernode.me:7891/account/get?address=NAFUNDBUKIOSTMD4BNXL7ZFE735QHN7A3FBS6CMY](https://aqualife2.supernode.me:7891/account/get?address=NAFUNDBUKIOSTMD4BNXL7ZFE735QHN7A3FBS6CMY)

他にも送金、メッセージ、マルチシグといった機能はWebAPI経由で利用することができます。APIの使い方は[NEM NIS API](http://i-yusuke.com/entry/nem-nis-api-document-japanese/)として公開されています（リンクは[Yusukeさん](https://twitter.com/yusukeito58)のページを使わせていただきます）。

WebAPIを使える開発環境であればどこでもNEMを利用できます。

### NEMライブラリ
WebAPIを更に使いやすくしたライブラリが豊富にあります。

| ライブラリ | 利用できる言語 | 用途 |
|:-----------------|:------------------|:------------------|
| [nem-sdk](https://github.com/QuantumMechanics/NEM-sdk) | JavaScript/TypeScript | Web、サーバー |
| [nem-library](https://github.com/NemProject/nem-library-ts) | JavaScript/TypeScript |Web、サーバー |
| [nem-php](https://github.com/evias/nem-php)|PHP |Web、サーバー|
| [nem-kotlin](https://github.com/ryuta46/nem-kotlin) |kotlin |Androidアプリ |
| [nem-swift](https://github.com/ryuta46/nem-swift)|Swift |iOSアプリ|

ウォレットの作成や送金処理を自前で実装するのは骨が折れる作業なのでアプリケーション開発する場合はライブラリを利用するのが主流です。

## NEMでどんなアプリケーションが作れるのか？
アイデア次第ですがNEMを使えば投げ銭、デジタルクーポン券、ファイルの証明などのアプリケーション開発が可能です。また既存のアプリケーションの機能の一部として導入することもできます。

- 生放送、ゲーム実況での投げ銭
- クラウドファンディング
- 店舗紹介サービスのデジタルクーポン券
- コンサートのデジタルチケット
- マッチングアプリのいいね数をNEMで代替。NEM資本主義のマッチングアプリ（笑）
- 契約書の証明
- 組織、チームで管理するデジタル金庫

などなど、NEMは低い開発コストで既存のサービスに導入できます。

## NEMを利用したアプリケーション開発に必要なもの
NEMは簡単で誰でも作れるという言葉を聞いたことがありますが、流石にプログラミングしたことない人が作れるっというわけではありません。NEMを用いたアプリケーションを開発するためにはプログラミングが必要です。

### 前提知識
#### ■ フロントエンドとバックエンド
Webを勉強している方は聞いたことありますが、フロントエンドとバックエンドという開発サイドの言葉があります。

__フロントエンド__とはユーザーが直接見て触る部分（UI/UX）のことであり、ブラウザ上やモバイルアプリケーション上で動作する開発サイドです。画面レイアウトや入力フォームの生成等の責務を担っています。フロントエンドのソースコードはブラウザ上から簡単に見ることができます。

__バックエンド__はユーザーが直接意識しない部分のことであり、サーバー側で動作する開発サイドです。フロントエンドからリクエストされた情報を元にデータベースへの読み書き等の責務を担っています。バックエンドのソースコードは管理者以外見ることはできません。よってデータベースを操作するようなアカウント作成や決済処理といった部分はセキュアに行うためバックエンドで実装します。

#### ■ NEMはフロントエンド？バックエンド？
NEMはバックエンドです。
NEMの送金、オリジナルコイン（モザイク）の発行など全てNEM（バックエンド）で行います。

よって、NEMを利用したアプリケーションを開発するためには画面や操作部を提供するフロントエンドの開発が必要になります。

またアプリケーションのコンセプトによっては他のバックエンドの開発も必要になります。

#### ■ 他のバックエンドで利用する
NEMはあくまでもブロックチェーンを利用した送金、オリジナルコインの発行などの機能を提供しているだけです。それ以外の機能を実装するためには他のバックエンドで開発する必要があります。例えば

- <font color="red">ユーザーの位置が大阪市内であれば</font>NEMを送金する
- NEMで署名した<font color="red">契約書の管理（ストレージデータベースへ保存）</font>

赤で色をつけている部分の処理はNEMではできないため他のバックエンドを利用します。

### プログラミング言語
フロントエンドとバックエンドで利用するプログラミング言語の一部を紹介します。

#### ■ フロントエンド
| 言語| 用途 | 備考 |
|:-----------------|:------------------|:------------------|
| HTML<br>JavaScript<br>CSS | Webアプリ<br>ホームページ | 昔からあるWeb開発用言語 |
| Angular.js<br>React.js<br>Vue.js | Webアプリ<br>ホームページ |JavaScriptで開発されたフレームワーク<br>低コストでWeb開発できるよう豊富な機能が提供されている |
|Objective-c<br>Swift| iOSアプリ |iOSアプリ開発用言語|
|Java<br>Kotlin| Androidアプリ | Androidアプリ開発用言語|

#### ■ バックエンド
バックエンドで利用されている言語と利用できる環境（サーバー）を提供しているサービスを紹介します。

| 言語 |サーバー提供サービス| 備考 |
|:-----------------|:------------------|:------------------|
| PHP | ロリポップ、xserver、AWS、Azure、GCPなど | 昔からあるWeb開発用言語 |
| Ruby on Rails |  Heroku、AWSなど |Rubyで開発された言語|
| Node.js | AWS、Azure、GCP（Firebase）など |JavaScriptで開発された言語 |

他にもありますがひとまずここまでで。

## 推奨する開発セット
フロントエンド、バックエンドともに手段がありすぎますね。
特にWeb開発は手段が多いため何が一番ええんやー！ってなってしまうかなと（笑）

ここでポイントとなるのは<font color="red">開発コスト</font>です。

ここでいう開発コストとは開発にかかる時間や費用などの人的リソースのことです。
開発工数とも言われており1日8時間と仮定され、1人で8時間かかる作業を1人日と表します。
エンジニアの単価を1時間あたり5,000円とすると1人日で40,000円の費用が必要です。
１ヶ月の営業日は20日とすれば１ヶ月にかかる開発コストは800,000円です。

つまり、エンジニアを一人雇うだけでも１ヶ月あたり800,000円の人件費が必要になります。

エンジニアの需要が高くなっている事やアジャイル開発が現在のビジネスにマッチしているという現状から<font color="red">少人数で早く開発できること</font>が必要とされています。

理想は1人でフロントエンドとバックエンドを早く開発できることです。

### フロントエンド
#### ■ Web
Web開発の場合は３代フロントエンドフレームワークとも言われる__Angular.js, React.js, Vue.js__を推奨します。なぜならWeb開発の実装でめんどくさい部分をフレームワークが解決してくれてるからです。

ソースコードの再利用のしやすさ、リアクティブ処理を容易に実装、「何書いてんのコレ？」ってなるようなDOM操作の排除など、
低い開発コストで実装できるよう手段として提供されています。

またそれぞれCLIが存在しており、コンソール上でCLIのコマンドを打てば開発テンプレートを自動作成してくれます。

そのフレームワークの中でも私は[__Vue.js__](https://jp.vuejs.org/index.html)を推奨します。
理由は従来のHTML/JavaScript/CSSの構成で実装ができるからです。従来のソースコードから容易に移植できる点がメリットです。

Vue.jsを学習したい方はこちらをご覧ください（随時更新中）。
[Vue.jsでWebアプリケーション開発の基礎と実務スキルを身につけるためのカリキュラム](https://github.com/Programmable-school/FrontendTraining)

#### ■ モバイル
モバイルアプリケーションの場合は手段が少ないため比較的に迷うことはないと思います。
iOSアプリであれば__Swift__、Androidアプリであれば__Kotlin__を推奨します。理由は従来使われていた言語（Objective-C、Java）より少ない記述でより安全にプログラムを書けるからです。

※FlutterやXamarinといった１つの言語で両OSのアプリを作れるプログラミング言語がありますが、ここではネイティブ言語だけとさせてください。

### バックエンド
[__Firebase__](https://firebase.google.com/?hl=ja)を推奨します。
FirebaseとはGoogleが提供しているmBaaSサービスであり、サーバーレスで少ない開発コストでバックエンド開発ができます。アプリケーション開発には欠かせない豊富な機能（ユーザー認証、データベース、ストレージ、バックエンド、プッシュ通知など）をFirebase上で利用できます。

サーバーレスによりアプリケーションのスケールに応じてFirebase側でサーバー管理してくれるため、こちらでサーバーの増強等の管理は不要です。

またセキュリティはFirebase独自のセキュリティ機能を設けており、データベースやストレージへのアクセス、バックエンド処理をセキュアに管理することができます。

さらにフロントエンドからデータベースをセキュアに操作することができます。これによって従来のようにデータベースを操作するためのWebAPIを作成する必要がなくなります（但しセキュリティルールをしっかり設定することが必要です）。

Uber、Spotify、クックパッドの新サービスであるKomercoでもFirebaseは利用されています。
[まだ間に合う！着々と進化しているFirebaseをまとめてみるよ #Firebase #FJUG](https://qiita.com/Yatima/items/23797ca868ee988c824b)

Firebaseのバックエンドサービス（Firebase functions）はnode.jsで動作しています。expressやTypeScriptの導入もできます。NEMのライブラリであるnem-sdkやnem-libraryの導入もできNEMの機能を簡単に利用することができます。

Firebaseの文献に関しては私の師匠のQiitaを紹介します。
[Norikazu Muramoto - Firebaseの人](https://qiita.com/1amageek)

## 図解
各アプリケーション毎に関係性を図で表してみました。

### ウォレットアプリ
フロントエンドから直接NEMを操作します。
アカウントの管理はフロントエンドのローカルストレージ上で行います。
#### ■ Web
![application_nem_wallet.png](https://qiita-image-store.s3.amazonaws.com/0/183031/ab179339-3dc0-9d96-301d-88ca992dc68d.png)

#### ■ モバイル
![application_nem_wallet_mobile.png](https://qiita-image-store.s3.amazonaws.com/0/183031/a64da922-7b06-35a8-fb69-aeddfcbd80ec.png)

### EC、マッチング、店舗紹介サービスなど
Firebaseでは認証、データベース、バックエンドでの処理、プッシュ通知等の機能を提供します。Firebaseのデータベースではユーザー、店舗情報とそれらに紐づく画像ファイルなどを管理します。

FirebaseからNEMを操作できます。
例えば誕生日のユーザーへNEMを送金するなどの処理を行う場合はFirebase内で以下の処理を行います。
名前、誕生日、NEMウォレット（送金先アドレスなど）の情報をFirebaseのデータベースに保存されていることが前提です。

1.　データベースからユーザー情報を取得　（今日の日付をクエリ指定）
2.　今日の日付がユーザーの誕生日かどうか判断　
3.　誕生日であればユーザー情報から取得した送金先アドレスへNEMを送金する

またフロントエンドから直接NEMの操作も可能です。

#### ■ Web
![application_nem_ec.png](https://qiita-image-store.s3.amazonaws.com/0/183031/e5a9864b-73c6-e950-482e-a612680f6d36.png)

#### ■ モバイル
![application_nem_ec_mobile.png](https://qiita-image-store.s3.amazonaws.com/0/183031/338a2e1c-7e54-a41d-31b4-805cee7421c5.png)

#### ■ 秘密鍵の管理
注意する点は__秘密鍵__の管理です。
送金などトランザクションを発生する場合は秘密鍵が必要です。秘密鍵の管理はフロントエンドのローカルストレージかバックエンドのデータベース（ここでいうFirebase上のデータベース）のどちらかで管理します。

どっちで管理するかは各アプリケーションのコンセプトによります。

フロントエンドで管理すると秘密鍵の管理責務が各ユーザーへ分散されるため比較的安全です。しかしアプリケーションのコンセプトによってはバックエンドで管理する必要があります。バックエンドのセキュリティを強化し、秘密鍵を平文ではなく暗号化して保存する必要があります。

また念のために秘密鍵をネットワーク通信路に流さないことも必要です。
具体的にはフロントエンドとバックエンド間で秘密鍵の受け渡しをしないということです。

SSLでやりとりされているため暗号化された状態で通信路を流れるので問題はないと思いますが、万が一の事を考え秘密鍵は安易に通信路へ流さないことを推奨します。

## 初心者がまずはじめに開発するべきアプリは
ウォレットアプリからはじめてみることを推奨します。
ウォレットアプリはWebやモバイルアプリケーションとして開発することができます（注意としてiOSアプリは法人アカウントをもっていないとリリースできません）。

ウォレットアプリにはアカウント作成や送金などNEMブロックチェーンを体感できる機能があり、それらを実装することで基本的な部分は学べます。

カンタンなNEMウォレットアプリケーションの作り方はこちらの記事にまとめていますのでぜひご覧ください。
[Vue CLI 3.0とTypeScriptを使ってNEMウォレットを作ってみた](https://qiita.com/hukusuke1007/items/132a4d3d3736c98125e8)

## おわりに
いかがでしたでしょうか。
NEMを使って何か作れそうなイメージができましたでしょうか？

WebAPIとして提供されているため様々なプログラミング言語でNEMを利用することができます。また既存のサービスへ容易に導入することができます。

同様に低コストで開発できるフロントエンドの__Vue.js__、バックエンドの__Firebase__の紹介をさせていただきました。これらを利用する事でNEMアプリケーションの開発が可能です。

- NEMで何か作りたい！
- NEMでこんなサービスを作ろうと思っているけど具体的にどう実現したらいいの？
- 既存のサービスにNEMを導入したい！具体的に教えて！

お気楽にご相談してください。

Twitterでのご連絡お待ちしております。
[shohei - Twitter](https://twitter.com/)