スマートコントラクトを用いたゲームの開発

## スマートコントラクト・ゲーム

スマートコントラクトは、NFTやゲームにおいて使われている技術である。
NFTやゲームでは、主にアイテムやキャラクターの所有権および取引をゲーム内で証明するための方法としてスマートコントラクトを用いている。
この記事では、ゲームの勝敗などの履歴や資金移動を簡単なDAppゲームの作成を通してスマートコントラクトで管理する方法について考える。

## スマートコントラクトとは？

詳しくは他の記事を参考にしていただきたいが、ブロックチェーンとはデータを署名付きで分散して保存することにより改竄を防止する方法である。スマートコントラクトはブロックチェーン上でプログラムを実行するためのプラットフォームである。データはブロックチェーン上に保存し誰でも参照が可能となる。ただし、トランザクション（書き込み）には費用(EthであればGas代)がかかる。

## DApp開発環境構築

スマートコントラクトを利用した分散アプリ(DApp)を作成するための開発環境を構築する。なお、macで開発、動作確認を行った。

truffleでDAppの開発を行う。truffleとはEthereumのスマートコントラクト開発時に使用する言語「Solidity」の開発フレームワークである。このフレームワークを用いることで簡単にSolidityのコンパイルやブロックチェーンへのコントラクトのデプロイ、Web3を用いたDAppの開発を行うことができる。
１. nodeのインストール(nodebrewなどで入れる)
```
# nodebrewによるインストール例(コマンド中のv16.10.0は適宜最新のstableなどに変更)
brew install nodebrew
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
nodebrew install v16.10.0
nodebrew use v16.10.0
```
２. truffleのインストール
```
npm install -g truffle
```
３. ReactでDApp開発をするためにtruffle boxでアプリを作成
truffleには簡単にDAppの開発を開始できる多くのテンプレート(box)が用意されている。今回はReactを用いてアプリ(ゲーム)を開発する。他のboxは以下から確認できる。
https://trufflesuite.com/boxes/
```
truffle unbox react
```
４. ganacheのインストール
ganacheでプライベートブロックチェーンを構築できる。ethパブリックブロックチェーンにデプロイするとトランザクションにリアルethが掛かるため、無料で開発するためにプライベートブロックチェーンを構築し利用する。以下サイトからインストール可能。
https://trufflesuite.com/ganache/

５. ウォレット（Metamask）のインストール
DAppとethのやりとりを行うためにChromeのエクステンションのウォレット(Metamask)をインストールする。以下サイトからインストール可能。
https://metamask.io/


## スマートコントラクトに保存する情報
対戦ゲームにおいて、以下の情報が保存対象として考えられる。
- ゲームの履歴（じゃんけんであれば各プレーヤーのハンド、ポーカーであればテーブル情報やプレーヤーのハンドなど）
- ゲームの結果、プレーヤー間やプレーヤーとホスト間の資金の移動履歴

これらをブロックチェーン上に保存し誰でも確認可能とすることで、ホストのゲームルールの歪曲や特定プレーヤーのハンドの優遇といった不正行為を監視することができる。また、ゲームに伴う資金移動も全て記録されるため、ホスト側が何か理由をつけて出金拒否をする場合も、根拠を持って問題行動をしていないと主張することができホスト側の出金拒否が不当であると証明しやすい。

## じゃんけんゲーム
簡単なゲームの実装例として、じゃんけんゲームを考える。ソースは以下のGithubにある。
じゃんけんゲームはプレーヤー１、２がハンド（グー、チョキ、パー）を選択し、両方のハンドが揃ったところで勝敗を判定してブロックチェーンに書き込む。ゲームに参加する際に各プレーヤーは同額の掛金をポッドに預け、じゃんけんに勝ったプレーヤーに賞金が支払われる。
なお、各プレーヤーがポッドに掛金を預ける際とじゃんけんゲームの結果を判定する際にはブロックチェーンへの書き込みが発生するためGas代がかかる。ゲーム判定のGas代はゲームマスターが手数料としてポッドから徴収したEthの中から支払うものとし、ポッドに掛金を預ける際のGas代は各プレーヤーが支払うこととする。

https://github.com/hellotaro/ethjankengame

#### スマートコントラクト上でサーバー処理を完結
ゲームとして作成、公開するためにはプレーヤーやゲーム状態の管理などはゲームサーバーで行い、ハンドやゲーム結果といったブロックチェーン上で公開したい情報のみをスマートコントラクトで管理することが一般的な構成であると思われる。しかし、じゃんけんという単純なゲームにおいてわざわざゲームサーバーを分けて実装するのは面倒なのと、プライベートブロックチェーンなのでGas代に本物のEthがかかるわけではなくGas代を気にしなくて良い。そのため今回はゲームの途中状態の管理なども無駄にGas代はかかるがブロックチェーンに書き込むこととし、ゲームサーバーは用意せずにスマートコントラクト上でゲームを実装する。

#### スマートコントラクトの作成
/truffle/contractsにJankenGame.solを作成。
JankenGame.solで行なっていることは、各プレーヤーのハンドを決定して２つのハンドが揃ったら判定を行う。
```
function setPlayerHand1(string memory _playerHand1, uint16 _playerId1) public;
function setPlayerHand2(string memory _playerHand2, uint16 _playerId2) public;
function calcGame() public;
```
/truffleディレクトリで以下コマンドを実行しコントラクトをコンパイル、デプロイする。
```
truffle compile
truffle migrate
```
コマンド実行後、Gasが使われていることが確認できる。

truffleでコントラクトを修正したい場合、以下のコードを実行することでデプロイされたコントラクトを修正できる。
```
truffle migrate --reset
```

#### ゲームアプリ(dApp)の作成
Reactで作成。react-bootstrapを使った簡単なフォーム入力UIである。
アプリは以下コマンドで実行するとブラウザが立ち上がる。
```
npm run start
```

#### ゲーム進行の様子
ganacheの自分のアドレス（一番上）のEthはコントラクトを作成したりPodへEthを送る度に減っていく。２番目はPodのアドレスである。

![スクリーンショット 2022-06-26 1.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517503/228a5407-62c4-9690-696b-53972be56448.png)

## 結果
簡単にReactで作成したアプリからEthのトランザクション作成、ウォレット間の送金、ブロックチェーン上の情報取得が行うことができ、ゲーム情報を検証可能な形でブロックチェーン上に保存することができた。じゃんけんゲームでなくポーカーなどのゲームにおいても各プレーヤーのハンドやテーブルを記録することで実用性がありそうだと思った。