誰でも簡単にブロックチェーンモバイルアプリを開発する

こんにちは。営業をやっていたりエンジニアっぽい事をやっています。ブロックチェーンをアプリに組み込むのって難しそうに感じますか？実は各ブロックチェーンプロジェクトからは開発用のSDKが公開されている事があり、これを利用することで簡単に組み込む事が出来ます。

今日はそのSDKとJavascriptによりアプリ開発が可能なExpoを活用して、アプリを動かす所までやってみたいと思います。

https://expo.dev/

本記事は少し連載します

[#1. 誰でも簡単にブロックチェーンモバイルアプリを開発する](https://qiita.com/faunsu/items/9670395a00e93c364151)
[#2. 誰でも簡単にブロックチェーンアプリを作り、送金する](https://qiita.com/faunsu/items/01062a0a7132d3843035)
[#3. 誰でも簡単にブロックチェーンアプリを作り、マイ残高確認アプリを作る](https://qiita.com/faunsu/items/8966ea9cd054214ee672)


# 環境準備
## 端末
パソコン ... Windows/Mac
スマホ ... iOS/Android

:::note warn
注意
M1 Macの方はRossetaに対応させる必要があります。本手順はIntel版Mac/Windowsでのみ有効です
:::

## 環境
- Node.js
    - Expo-cli@5.3.0

# 最初に
## 実行用アプリのインストール
Androidの方は以下のアプリをインストールして下さい

https://play.google.com/store/apps/details?id=host.exp.exponent&hl=ja&gl=US

iPhoneの方は以下のアプリをインストールして下さい

https://apps.apple.com/jp/app/expo-go/id982107779

## Node.jsのインストール
まずは手始めにNode.jsをインストールしましょう。以下URLにアクセスし、推奨版（LTS）と表示されているものをインストールしましょう

https://nodejs.org/ja/

## Expo-cliのインストール
Expoを動作させる為に必要です。インストールしましょう。まずは手始めに前の手順であるNode.jsが問題なくインストールされているか確認しましょう。Macの方は`ターミナル` Windowsの方は`コマンドプロンプト`を起動して以下を実行して下さい

```terminal
npm -v
```

もし数字だけが表示されたら成功ですが（例：6.14.16）、npmは存在しません、みたいなエラーが表示された際にはセットアップに失敗していますので、Node.jsのインストールをやり直して下さい

上記が問題なく実行できたら次は以下を実行しましょう

```terminal
npm install --global expo-cli
```

上記がエラーなく実行が出来たら以下を実行してみて下さい。 `npm -v` 同様、数字が表示されたら問題ありませんので次へ進んで下さい
```terminal
expo-cli --version
```

# プロジェクトの作成と編集
早速アプリを作っていきましょう。まずは土台を作成します。Macの方は`ターミナル` Windowsの方は`コマンドプロンプト`を起動して以下を実行して下さい

### Macの方
```terminal
cd ~
expo init blockchain-project
```

### Windowsの方
```terminal
cd %HOMEPATH%
expo init blockchain-project
```

以下のような選択肢が表示されると思います。
上下キーで移動できますので、 `blank（Typescript）` を選択しましょう。

```terminal
? Choose a template: › - Use arrow-keys. Return to submit.
    ----- Managed workflow -----
    blank               a minimal app as clean as an empty canvas
❯   blank (TypeScript)  same as blank but with TypeScript configuration
    tabs (TypeScript)   several example screens and tabs using react-navigation and TypeScript
    ----- Bare workflow -----
    minimal             bare and minimal, just the essentials to get you started
```

自動でプロジェクトの作成が始まります。処理が終わるまで暫くお待ち下さい。
以下のような画面が表示されたら成功です。

```terminal
✅ Your project is ready!

To run your project, navigate to the directory and run one of the following npm commands.

- cd blockchain-project
- npm start # you can open iOS, Android, or web from here, or run them directly with the commands below.
- npm android
- npm ios
- npm web
```

:::note warn
注意事項
上記の出力が `npm start` ではなく `yarn start` となっている場合があります。その場合は以下段落以降 `npm` の文言を `yarn` に置き換えて進めて下さい
:::

まだこの段階ではBlockChainは組み込んでいませんが、まずはこの状態でアプリとして実行してみましょう
上記で表示されているように、Macの方は`ターミナル` Windowsの方は`コマンドプロンプト`にて以下の通りに実行して下さい



```terminal
cd blockchain-project
npm start
```

すると画面にQRコードが表示されます。これをスマホのQRコードリーダーで読み取ってみましょう
※ Androidの方は事前にインストールしたExpoアプリ内にもQRコードリーダーが内蔵されています。iOSは標準のQRコードリーダーを利用下さい

スマホの画面に `Open up App.tsx to start working on you app!` と表示されましたらアプリとして実行成功です。おめでとうございます。

では一旦パソコンの Macの方は`ターミナル` Windowsの方は`コマンドプロンプト` に戻りまして `CTRL+C` キーを押して一旦実行中のスクリプトを終了しておきます。
※ この時に ターミナル、もしくはコマンドプロンプトは終了せず、そのままにしておいて下さい

## ブロックチェーンを組み込む
今回はSDKが提供されているブロックチェーン Symbol を使ってみます。

https://symbol.fyi

先ほどのコマンドプロンプトに戻り、以下を実行して下さい

```
npm install symbol-sdk@1.0.0 rxjs@6.6.3 buffer events process util react-native-expo-crypto react-native-expo-bitcoinjs-lib readable-stream expo-random
```

次に以下の通りに実行して下さい

### Macの方
```
touch metro.config.js
touch shim.js
open .
```
### Windowsの方
```
copy nul metro.config.js
copy nul shim.js
explorer .
```

この段階でWindowsの方はエクスプローラ、Macの方はFinderが立ち上がっていると思います
以下のファイルをWindowsの方はメモ帳、Macの方はテキストエディットで開きましょう

1. metro.config.js
1. shim.js
1. App.tsx

それぞれのファイルの中身を以下の通りに差し替えをして下さい

```javascript:metro.config.js
module.exports = {
  resolver: {
    extraNodeModules: {
      crypto: require.resolve("react-native-expo-crypto"),
      stream: require.resolve("readable-stream"),
      buffer: require.resolve("buffer"),
      events: require.resolve("events"),
    },
  },
};
```

```javascript:shim.js
if (typeof __dirname === 'undefined') global.__dirname = '/';
if (typeof __filename === 'undefined') global.__filename = '';
if (typeof process === 'undefined') {
  global.process = require('process');
} else {
  const bProcess = require('process');
  for (var p in bProcess) {
    if (!(p in process)) {
      process[p] = bProcess[p];
    }
  }
}

// process.browser = false;
if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer;

global.location = global.location || { port: 80 };
const isDev = typeof __DEV__ === 'boolean' && __DEV__;
process.env['NODE_ENV'] = isDev ? 'development' : 'production';
if (typeof localStorage !== 'undefined') {
  localStorage.debug = isDev ? '*' : '';
}

// If using the crypto shim, uncomment the following line to ensure
// crypto is loaded first, so it can populate global.crypto
// require('crypto')
```

```tsx:App.tsx
import "./shim";
import { StyleSheet } from 'react-native';
import React, { useLayoutEffect, useState } from "react";
import { StatusBar } from "expo-status-bar";
import { Account, NetworkType } from "symbol-sdk";
import { View, Text } from "react-native";

export default function App() {
  const [privateKey, setPrivateKey] = useState<string>("");
  const [address, setAddress] = useState<string>("");


  useLayoutEffect(() => {
    const account = Account.generateNewAccount(NetworkType.TEST_NET);
    setPrivateKey(account.privateKey);
    setAddress(account.address.pretty());

  }, []);

  return (
    <View style={styles.container}>
      <Text>Hello Symbol BlockChain!!</Text>
      <Text style={{ marginTop: 20, textAlign: "left" }}>
        アカウントの秘密鍵（第三者には共有してはなりません）
      </Text>
      <Text style={{ marginTop: 10, textAlign: "left" }}>
        {privateKey}
      </Text>
      <Text style={{ marginTop: 20, textAlign: "left" }}>
        アカウントのアドレス
      </Text>
      <Text style={{ marginTop: 10, textAlign: "left" }}>
        {address}
      </Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

差し替えは出来ましたか？
出来ていましたらMacの方は`ターミナル` Windowsの方は`コマンドプロンプト`にて以下の通りに再度実行し、アプリを実行しましょう

```
npm run start
```

また、QRコードが表示されると思いますので、これをQRコードリーダーで読み取ってアプリを起動します。
すると先ほど起動時のアプリが残っている場合がありますので、画面が先ほどと変わらない場合は Macの方は`ターミナル` Windowsの方は`コマンドプロンプト`にて `r` と打ち込みましょう。更新されます。

これでアプリ画面上にブロックチェーンの秘密鍵とアドレスが表示されていたら成功です！
これにてアプリへブロックチェーンの実装が出来ました。今回はアカウントを作っただけですが、もちろん送金や署名等も出来ます。
より詳細に色々やってみたい方はこちらのドキュメントを参照するか、以下Twitterアカウント等へメンションしてみて下さい。
親切な方が教えてくれるかもしれません

ドキュメント

https://docs.symbol.dev/

Twitter

https://twitter.com/thesymbolchain/status/1507610357417713666

Discord

https://discord.gg/5CKEnxsJkX


最後にオススメ記事（私の記事ではありません）

https://qiita.com/nem_takanobu/items/4f50e5740318d92d7dcb