ブロックチェーン技術を利用してアイテムを交換するゲームを作った話

この記事は [nem Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nem-2)の23日目の記事です。
前日は @y-sakata さんの 「[NEM2のSDKを作っててハマったこといろいろ](https://qiita.com/y-sakata/items/9a7642f5437f862f7b22)」でした。

# はじめに

次世代NEMに搭載予定のCatapultエンジンを使って、ユーザー間でアイテム(固有資産)を交換しながらブロックチェーンの仕組みを体感できるゲームを作成してみました。
技術的な解説記事は「[アイテム交換ゲームが示すNEMブロックチェーンの可能性](https://qiita.com/nem_takanobu/items/8a1907d09b01219cdb3b)」をご覧ください。

注）ここで紹介するプログラムは一般的な「ゲーム」であり、収益をあげる目的で使用される、いわゆる「ブロックチェーンゲーム」とは関係ありません。

# 目的
ブロックチェーンでアイテム（固有資産）の所有を実現します。
ブロックチェーンで第三者の仲介不要なアイテム（固有資産）交換を実現します。
ブロックチェーンの透明性により、外部からゲーム勝敗の検証が可能になります。

# ゲーム概要

勇者アカウントとアイテムを2つ作って冒険を開始します（自動生成）。
勇者はアイテムを友達と交換しながら魔王を倒す冒険に出ます（冒険ボタンクリック）。
自分のパラメータと相性の合うアイテムが揃ったら、勇者は魔王を倒すことができます。

# 操作方法

ここからゲームを開始してください。
[アイテム交換クエスト](http://xembook.net/nem2-sdk/501_exchange_item.html)

Catapult のテストネットを利用しており、何度でもやり直すことができるので気軽にお試しください。

### 初期表示画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/eb094405-f14f-c132-cc15-df746222d47b.png)

アカウントが割り振られ、アドレスとゲーム上での属性(element)が表示されます。
属性は(火、水、木)があり、火は水に弱く、水は木に弱く、木は火に弱いものとします。
アイテムにも同じように属性がありますが、それは非表示としています。

では、ゲームを進めるために必要な手数料を蛇口サービスから送金しましょう。
蛇口ボタンをクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/902582aa-8e93-4dc3-8c70-9a5060c382d0.png)

この画面は今回のプログラムとは別に準備された外部の送金システムです。
※ブロックチェーン技術を利用すると、このように利害関係の無いサービスからでも情報をやり取りすることができます。

入金先と必要手数料額は自動的にセットされるので、そのままCLAIM!ボタンをクリックしてください。
クエストページに戻り、しばらくローディングアイコンを眺めていると入金が完了します(15秒程度)。
自動的に名称登録ダイアログが表示されるので好きな名前を**半角英数字だけ**で登録してください。

> 注）存在チェック未実装ですので、なるべく他の人と重複しないような名前を指定してください。
一度間違って登録すると30日間その名前は他で使用できなくなります。ブラウザの反応がなくなった場合は上記URLに `?cmd=rest` を追加してリロードしてください。秘密鍵を再取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/0fec0982-4772-4f5f-b2bf-e90810bdb33e.png)

OKボタンをクリックすると、以下の処理を一括で登録します。

- ユーザー名のネームスペース登録
- アイテム1名のネームスペース登録
- アイテム2名のネームスペース登録
- アイテム1をユーザにマルチシグ登録(1-of-1)
- アイテム2をユーザにマルチシグ登録(1-of-1)

ネームスペースとはインターネットのドメインのようなもので複雑なアドレスを覚えなくても一意にユーザーやアイテムのアカウントを特定することができます。また、1-of-1のマルチシグとは1つのアイテムアカウントに対し1人のユーザアカウントの承認が必要な署名構成を作るということで、アイテムアカウントの資産はユーザにロックされることになります。
細かい内容は省略しますが10個のトランザクションが集約されて1ブロックに詰め込まれます。
以下のように表示されたら成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/b5199e59-9c68-1c59-b902-6f208764e0f3.png)

NEMアカウント２つがアイテムとして登録され、ユーザにマルチシグとして紐づけられました。これらのマルチシグ情報を変更できるのはユーザだけのため、この状態はユーザがアイテムを所有していると認識することができます。
冒険に出るボタンが表示されましたね、では今の装備で大丈夫かどうか冒険してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/09ee9e96-5076-78d8-b3e8-bab368e91f23.png)

物語が残念な結果に終われば、他のユーザとアイテムを交換する必要が出てきます。
SNSなどを通じて他のユーザを探します。今回book3さんがxxbsheildを自分のxbsheildと交換してくれると話がまとまりました。
自分のあげるアイテムの右側から交換ボタンをクリックすると以下のようなダイアログボックスが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/cdc3a495-aed0-1ae9-3667-5fd72342b687.png)

自分のあげるアイテムは自動入力されているので、誰の何が欲しいかを入力してOKボタンをクリックします。
（申請には手数料10がデポジットとして必要なので、足りない場合は蛇口から足しておきましょう）
しばらく待つと登録が完了します。しかし、これで交換完了ではありません。
交換対象のユーザがクエストページを開くと以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/017fdce5-1971-2b5f-9615-b45cffe2c526.png)

内容に間違いがなければ、OKボタンをクリックして交換を完了させます。
このアクションでアイテムが同時に交換されます。ユーザー間の勝手な合意なのにもらったまま逃げるということはできません。
何かのアクシデントでブロックチェーンが巻き戻しになった場合も、この交換前か交換後かどちらかの状態で一貫性が保たれます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/6339f340-bc1b-bc57-8a17-1bcb6fbaaf43.png)

交換が完了しました。さあ、再び冒険に出かけましょう。
あなたは無事魔王を倒すことができるでしょうか！

# プログラム解説

技術的な解説記事は「[アイテム交換ゲームが示すNEMブロックチェーンの可能性](https://qiita.com/nem_takanobu/items/8a1907d09b01219cdb3b)」をご覧ください。

主な解説ポイントは以下の通りです。

- NFTなど特殊実装にたよらない固有資産の交換について
- 第三者の仲介を不要とするトランザクションの集約について
- 外部からでも検証可能な永久に消せないゲームについて

# まだ実装できていないところ
##### リファクタリング！
30分前に完成したので、ソースコードは超汚いです。アドカレ特有の現象としてご了承ください。

##### パラメータの微調整
すんなりクリアできる人もいれば、なかなかクリアできない人もいます。
クリアできた人は他の人にアイテムを譲ってあげましょう。

##### サブネームスペースの活用
プログラムの簡略化のためにルートネームスペースのみ利用しました。
サブネームスペースを活用すれば手数料の費用を抑えることが可能です。

##### HTTPS対応
HTTPS対応のテストネットがないため、一部のブラウザでは利用できないかもしれません。

##### セキュリティ
ローカルストレージに秘密鍵まるまる保存しています。ゲーム用途でのみお試しください。

##### 入力チェック等
登録内容に不具合があると画面が反応しません。リロードしてみるか、URLに `?cmd=reset`を追加して再表示してみてください。秘密鍵再取得となり、今までのアイテムデータがすべて消えますのでご注意ください。

##### メタ情報の登録
このアイテムは火の属性と相性が良いなどが伝承されたり、画像と紐づけて一覧表示させたり。楽しさ無限大ですね。

##### 取引所
あると面白そうですね。