SORACOM LTE-M Button Plusのデータをブロックチェーンに記録した話

概要
===

SORACOM LTE-M Button Plusを買ってみたので遊んでみました。
最終的にこの記事ではボタンをクリックしたことを検知してブロックチェーンにデータを記録します。
事前にいくつか準備することがありますが思ったより簡単にできますのでぜひやってみてください。

**今回使用したデバイス情報**

https://soracom.jp/store/5207/

事前に学習しておくと良いこと
===

* [SORACOM IoT レシピ IoTでドアの開閉モニタリング](https://soracom.jp/recipes_index/2966/)
* [SORACOM Beam](https://soracom.jp/services/beam/)について
* [Symbol](https://docs.symbol.dev/ja/index.html)というブロックチェーン


技術概要
===

今回の全体的な技術概要はこんな感じ。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/c2742ebf-9632-1afe-90b4-44f7efb763ff.png)

SORACOM LTE-M ButtonをクリックしたらBeamでサーバーへデータを転送し、そこからブロックチェーンへデータを書き込む（トランザクションを送る）

# サーバー側の説明

サーバー側のコードはSymbolが提供してる[TypeScript& JavaScript SDK](https://docs.symbol.dev/ja/sdk.html)（※）でJavascriptが扱えるので、今回初めて[Express](https://expressjs.com/ja/)なるものを使ってやってみました。Expressは今回初めて触ったので色々と至らない点があるかもしれませんがご了承ください。

:::note warn
※ 現在 symbol-sdk v3.0.0がアルファ版としてリリースされています。v2.0.0はdeprecatedです。v3ではrxjsに依存した多くの機能が削除されるため、REST APIへの直接アクセスが必要となります。
:::

## サーバー環境
* Node.jsが使えること
* Docker及びdocker-composeが使えるとより便利です。


今回使うソースコードは以下。後ほどサーバーへデプロイします。

https://github.com/ishidad2/soracom-iot



準備するもの
===

* [SORACOM LTE-M Button Plus](https://soracom.jp/store/5207/)
* サーバー（[さくらのVPS](https://vps.sakura.ad.jp/)や[Contabo](https://contabo.com/en/)など）
* テキストエディタ（私は[VSCode](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)推しです）
* SSHクライアント（teratermなど）
* Symbolアドレス（**[デスクトップウォレットのダウンロードとインストール、テストXYMの取得まで（テストネット編）](https://nemlog.nem.social/blog/76773)を参考に事前にSymbolアドレスを作成しておいてください**）

https://nemlog.nem.social/blog/76773


手順
===

それではまずは、SORACOMの設定から始めます。

# SORACOM LTE-M ButtonのBeam設定を行う

* [SORACOM IoT レシピ IoTでドアの開閉モニタリング](https://soracom.jp/recipes_index/2966/)
ここと同じようにSORACOMコンソールからBeamの設定を行っていきます。
まずはSORACOMコンソールにログインしておいてください。

## SIMグループ設定

* 既にSIMグループを作成してる場合は作成してるグループを選択してください。
* まだグループを作成していない場合は「追加」からグループを作成してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/f63ec193-29b5-1107-f4e3-17d87b696d89.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/21e25803-ebf5-244e-ded6-60e27ecff288.png)

## Beamの設定

* 上部のタブ「基本設定」内の「SORACOM Beam 設定」を開きます。
* 「設定を追加する」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/782fe80b-85df-e250-946b-8de82272b3e3.png)

「UDP→HTTP/HTTPSエントリポイント」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/bee83d6b-dbd3-bb4e-d722-eb1535a9feee.png)

## Beamの転送先設定

* 以下の設定にしてください。

:::note 
* プロトコル：HTTP
* ホスト名：ご自身が使用するサーバーIP
* ポート番号：3002
* パス：/api/v1/soracom
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/7162b3c9-3cb7-1d37-1bb2-30365d2babec.png)

Beamの設定は以上です。
「保存」を押して完了してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/3e104fe2-ce12-e11b-4859-a72a5aaee429.png)

最終的に下記のようになっていればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/4f9d68cb-cc9e-e514-8d1e-c2b01a052e37.png)

SORACOMの設定は以上です。

Beamの受け口（VPSサーバー側 API）の構築
===

次にBeamで転送する先のAPIサーバーを構築します。

# 事前準備

・SymbolデスクトップウォレットでSymbolアカウントを作成しプライベートキーを取得
※アカウントにはトランザクションを発生させるための手数料分のXYMが必要です。

今回使用するSymbolについてはこちらがよくまとまっていてわかりやすいです。興味がある方は参考にしてみてください。
今回はスキップしても大丈夫です。

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


* アカウント生成については[デスクトップウォレットのダウンロードとインストール、テストXYMの取得まで（テストネット編）](https://nemlog.nem.social/blog/76773)を参照。

## Symbolプライベートキー（秘密鍵の取得方法）

[デスクトップウォレットのダウンロードとインストール、テストXYMの取得まで（テストネット編）](https://nemlog.nem.social/blog/76773)を参考に作成したウォレットの状態から説明します。
右側「アカウント」タブを選択してアカウントの情報を表示します。
下記図の赤枠の「表示」をクリックしてパスワード入力後、秘密鍵を表示します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/1de0c4d2-9456-532d-1c12-ab580811133c.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/716f1688-8157-cfae-5b77-bd1795b4574f.png)

下記図の赤枠の部分をクリックしてSymbolプライベートキー（秘密鍵）をコピーします。（秘密鍵は人に教えてはいけません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/478ec1f1-c69f-3e13-0199-6e9992665857.png)

コピーした秘密鍵は後で使いますのでどこかにメモしておいてください。
ウォレットでの操作は以上です。

# サーバー構築

サーバーへSSH等で接続後、下記のGithubリポジトリよりプロジェクトをCloneしてください。

https://github.com/ishidad2/soracom-iot

:::note warn
サーバー側ではブロックチェーンへボタンのデータを記録するため、事前にSymbolアドレスが必要になります。
:::

先程取得したSymbolプライベートキー（秘密鍵）は.envに記載します。

## デプロイ

```bash
git clone https://github.com/ishidad2/soracom-iot
cd soracom-iot/src
npm install
```

## 設定ファイルの作成

src/config以下.env.exmapleをコピーまたはリネームして使用
Symbolアドレスのプライベートキー（秘密鍵）を記入

```
cp .env.example .env
vi .env
```

```
...
# private key
CERTIFICATE_PRIVATE_KEY=****CF13DFA15E5DC35BA0584BD79CAC2****************************
```

## コンテナの起動

Dockerがインストールしてある環境であれば下記のコマンドでコンテナが起動します。※要docker-compseコマンド

```
cd ~/soracom-iot
docker-compose up
```
コンテナが起動すると下記のようなメッセージが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/2620dc4c-bdd8-506c-ed5c-a9d1c7ae0c46.png)

## アクセス確認

以下のURLにアクセスします

```
http://〇〇.〇〇.〇〇.〇〇:3002
```
※〇〇にはデプロイ先のIPアドレスが入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/65a868f0-d9ed-3d89-87e1-d1e1fde423a6.png)


上記のように表示されればOKです。

## Docker以外での起動

Dockerがインストールされていない場合にはsrcフォルダへ移動して下記のコマンドで起動します。
※もしこちらで起動した場合は接続ポートが違うのでSORACOMの設定も変更する必要があります。（ **ポート番号は3000番です** ）

```
cd ~/soracom-iot/src
npm run dev
```

* Docker及びDocker以外**で起動したサーバープログラムの停止はCtrl+C**で行えます。

## エンドポイント

### GET

```
/api/v1/soracom
```

例)http://〇〇.〇〇.〇〇.〇〇:3002/api/v1/soracom

GETでアクセスするとブロックチェーン接続先のノードとネットワークが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/ce5a3d70-8f1f-bfae-5f17-7cb6dedff6a8.png)

GETはサーバープログラムが正常に動いていることを確認するだけのものです。

### POST

今回の本題はこちら。

```
/api/v1/soracom
```

https://github.com/ishidad2/soracom-iot/blob/main/src/routes/soracom.js#L21

```javascript
router.post('/v1/soracom', async function(req, res, next) {
  const repo = new sym.RepositoryFactoryHttp(node);
  const txRepo = repo.createTransactionRepository();
  const networkRepo = repo.createNetworkRepository();
  const networkType = await networkRepo.getNetworkType().toPromise();
  const medianFeeMultiplier = (await networkRepo.getTransactionFees().toPromise()).medianFeeMultiplier;
  const epochAdjustment = await repo.getEpochAdjustment().toPromise();
  const networkGenerationHash = await repo.getGenerationHash().toPromise();
  const signerAddress = sym.Account.createFromPrivateKey(process.env.CERTIFICATE_PRIVATE_KEY, networkType); //送信元アドレス
  const strMessage = JSON.stringify(req.body);

  const tx = sym.TransferTransaction.create(
    sym.Deadline.create(epochAdjustment),
    signerAddress.address,
    [],
    sym.PlainMessage.create(strMessage),
    networkType,
  ).setMaxFee(medianFeeMultiplier);

  //署名して送信
  const signedtxd = signerAddress.sign(tx, networkGenerationHash);

  console.log("hash:"+signedtxd.hash);
  console.log("payload:"+signedtxd.payload);

  txRepo.announce(signedtxd).subscribe((x)=>console.log(x),(er)=>console.log(er));
  
  res.send("ok");
});
```

このエンドポイントがSORACOM Beamからのデータを待ち受けています。
合わせてこのエンドポイントはSORACOM Beamからデータを受信したらSymbolブロックチェーンへのトランザクションを発生させる役目も担っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/2a44228f-e40a-8552-544c-f70219784c8b.png)

では、実際にSORACOM LTE-M Buttonを押してデータをサーバーに送り、ブロックチェーンへそのデータを記録して見ましょう。

サーバープログラムが起動しているのを確認したらボタンを押します。

ボタンをクリックしてしばらくするとサーバー側へ下記のようなログが出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/5059e6ef-4723-d723-6aea-86b6a94420a7.png)

以下、実際に実行した際の様子です。

![index.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/0aa356fb-81b7-1b82-ab95-297c28f0f88a.gif)


下記よりボタンを押した際のデータがトランザクションとして送信され、ブロックチェーンに記録されていることが確認できます。

https://testnet.symbol.fyi/transactions/CA51498D83674295263FBDA14F69E02C7400767D997A20C79204701762168165

```
Button -> SORACOM Beam -> Server -> BlockChain
```
上記の流れでデータが送られています。

# 最後に

今回はSORACOM LTE-M Buttonを使って簡単にメールを送ったり、クリックしたことをブロックチェーンに記録したりしました。
SORACOM LTE-M Buttonボタン以外でも、例えば[GPSマルチユニットSORACOM Edition（バッテリー内蔵タイプ）スターターキット ](https://soracom.jp/store/5235/)なども同じ様にSORACM Beamを使えば任意のサーバーへデータを送信することが出来ます。
簡易な自分用のGPSトラッカーなどを作ることもできそうです。使い方次第ではとても面白いことができそうですね。
※めっちゃSORACMを推してますが、私はSORACM社の回し者ではありませんので誤解されませんように（笑）


その他、参考
===

SORACOM LTE-M Button Plusを使うには利用料金（添付図参照）がかかります。利用に関しては自己責任でお願いします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/810a0ef4-db4e-8d1d-cb43-1186d640af70.png)


ボタンを押した場所を簡易測位も出来るようです。色々と組み合わせるとなにかできそう。

https://soracom.jp/recipes_index/2967/

Symbolについて深く学びたい方はこちらを参考にされると良いと思います。

https://github.com/xembook/quick_learning_symbol