ブロックチェーンゲームの作り方2 基本編Part2

[Previous << 1 - 基本編Part1](https://qiita.com/flowcadence/items/8cc25249cda37364cac1)
[Next >> 3 - 基本編Part3](https://qiita.com/flowcadence/items/2911220eb06a20beea14)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95

:::note
**Flow blockchainのもう一つの特徴は[リソース・プログラミング](https://qiita.com/flowcadence/items/87147a26f1d2b89b46ca#a-new-programming-language)です。**
これはリソースを手に入れておけば、そのリソースのメソッドを自由に呼び出せるというものです。例えば武器屋リソースがあれば武器を売ったり買ったりでき、盗賊リソースがあれば相手の城からお金や金品を頂いたり、戦士リソースであればHPを犠牲にして味方を守ったり、このようなリソースを自由に考えて、作り、ユーザーに配布し、使ってもらうことができます。これらはアイデア次第であり、且つ、誰でも自由に作れます。

但し、これらメソッドはトランザクションであり、本来お金やNFTを移動させるものであるため、ユーザー自身はたとえゲームとわかっていても無闇にしないものであることにご注意ください。これらトランザクションは実装次第でユーザーの負担を和らげる方法があり<sup>[[脚注1]](#脚注)</sup>、それらについては5 ~ 9で解説します。

**NFT**は本来このリソースの一案として考案されたもの(Flow blockchainの開発者はERC-721 Non-Fungible Tokenの設計者)なので、あなたの思いついたリソースがNFTと同じくらい人気が高まれば、ユーザーはこぞってトランザクションを実行することでしょう。( NFTはイーサリアム上で動くCryptoKittiesゲームの帽子や鞄を所有できるようにしたもの<sup>[[脚注2]](https://qiita.com/flowcadence/items/bd9dd37723dab0557064#%E8%84%9A%E6%B3%A8)</sup>なので、理論上これより価値のあるリソースを考えることは不可能ではありません。)


**TL;DR [ESportsゲームも参考になると思う](https://devfolio.co/projects/code-of-flow-a0cd)けど他に参考になるアプリはないの?**

参考になるFlowブロックチェーン・アプリといったらこの人のしかないでしょう、Jacob Tucker氏!

Flowブロックチェーンアプリの開発方法を世界中に教えてくれた人物です。

YouTube: ↓
:::

https://www.youtube.com/@jacobmtucker/videos

:::note
このYouTubeチャンネルは非常に評判が良く、2022年ごろのアプリ開発者のバイブル的に人気を博しました。2021年のパート1から順に見てみることをおすすめします。
***
**参考になるFlowアプリを触る！**

彼が1年前に作成した、SvelteKit Webフレームワークを使用した[HelloWorldアプリ](https://www.youtube.com/watch?v=plkPyQx-H3U)をここでご紹介します。

半年前にCadenceがバージョン1.0になった為、少し修正が必要なのですが…!?
:::

#### [Why Flow](https://qiita.com/flowcadence/items/b6acebdde2b9a6a417c3#flow-token)
> FLOW（または$FLOW）トークンは、Flowネットワークのネイティブ通貨です。開発者およびユーザーは、FLOWを使用してネットワーク上で取引(transact)を行うことができます。開発者は、ピアツーピア決済(他人同士の決済)、サービス料金徴収、または消費者向け特典(rewards)のために、FLOWを直接アプリに統合することができます。 

ということでやっていきます、P2P(ピアツーピア)決済アプリ開発!

今回は既にあるv1.0未満で開発されたプロジェクトをv1.0で動くようにします。

#### 既存のHelloWorldプロジェクトをインポート

https://github.com/emerald-dao/0-hello-world-svelte

上記サイトのプロジェクトは初学者向けに非常に良いプロジェクトを提供しているのですが、これがv1.0未満のバージョンで作られているので、これをv1.0に対応させて、その動きを見てみます。

:::note warn
💡もし、エミュレータの起動方法やスマートコントラクトのデプロイについて操作に自信がない場合は[こちら](https://qiita.com/flowcadence/items/8cc25249cda37364cac1)を参照してください。
:::


以下コマンドをVSCodeのTerminalウィンドウで実行します。
```
> git clone https://github.com/emerald-dao/0-hello-world-svelte.git
```

0-hello-world-svelte フォルダをVSCodeで開きます。

#### `npm install`

下記コマンドを実行します。
```ruby
npm install
```
![スクリーンショット 2024-12-29 15.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/e6e39f55-b130-e991-3267-14b18a423495.png)

#### プロジェクトをローカルで動かす

`.env.example`を`.env`にリネームします。

![スクリーンショット 2024-12-29 15.36.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/8effdf7d-d274-0968-9b34-1334b93d4b96.png)

下記コマンドを実行します。
```ruby
npm run dev
```
Output:
```ruby
> 0-hello-world-svelte@0.0.1 dev
> vite dev


Forced re-optimization of dependencies

  VITE v4.5.5  ready in 508 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help
```
出力されたlocalhostのURLをブラウザに貼り付けて、表示します。
![スクリーンショット 2024-12-29 15.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/0b6db560-d8c8-f152-c68f-81c0e65ce502.png)

#### エミュレータを起動する

VSCodeでターミナルウィンドウをもう一つ開き、以下コマンドを実行します。
```ruby
flow emulator -v
```

#### コントラクトをデプロイする

VSCodeでターミナルウィンドウをもう一つ開き、以下コマンドを実行します。
```ruby
flow project deploy
```
*しかし、この時点ではv1.0以前のCadenceバージョンで書かれているために以下のような出力が表示され、デプロイが失敗します。*

Output:
```ruby
❌ Command Error: Parsing failed:
error: `pub` is no longer a valid access keyword
 --> :1:0
  |
1 | pub contract HelloWorld {
  | ^^^

error: `pub` is no longer a valid access keyword
 --> :3:4
  |
3 |     pub var greeting: String 
  |     ^^^

error: `pub` is no longer a valid access keyword
 --> :5:4
  |
5 |     pub fun changeGreeting(newGreeting: String) {
  |     ^^^
```
:::note warn
`pub`はv1.0以前のCadenceで有効だったアクセス修飾子ですが、v1.0では`access(all)`と記載する必要があります。
:::

#### コントラクトを修正する

`/src/lib/flow/cadence/contracts/HelloWorld.cdc`を開きます。

![スクリーンショット 2024-12-29 15.51.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/e3880deb-9ffd-8b58-e7cf-440ba0744f15.png)

VSCode のExtentionが、このように修正すべきところに赤の波線を表示しています。
`pub`を全て`access(all)`に置き換えます。

再度、以下コマンドを実行します。すると、正常にスマートコントラクトがエミュレータ上にデプロイされました。
```ruby
flow project deploy
```
Output:
```ruby
Deploying 1 contracts for accounts: emulator-account

HelloWorld -> 0xf8d6e0586b0a20c7 (bd0928d3d76a704e6a6e9d46fcced2f9db62ca34e2f91dd2a71afbd30847857a) 

🎉 All contracts deployed successfully
```

#### Dev Walletを起動する

エミュレータが起動している状態で、以下コマンドを実行します。
```ruby
flow dev-wallet
```
この状態でブラウザをリフレッシュし、画面右上の`Connect`をクリックすると、以下のようなウォレットを選択する画面が表示されます。
![スクリーンショット 2024-12-29 16.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/9a5ebdc6-842d-c15d-a203-78a5cd9fbcb4.png)

### ウォレットの設定部分のエラーを修正する

`src/lib/flow/config.ts` をVSCodeで開くと以下のように、以下の修正すべきところに赤の波線が表示されています。

![スクリーンショット 2024-12-29 16.10.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/7a117ada-3714-9aec-b5cf-9f0bcfdae210.png)

これはTypescriptによるエラーであり、既にメンテナンスがされていない為と推測されます。
`src/lib/types/@onflow/index.d.ts`を削除するとエラーが表示されなくなります。

※`src/lib/flow/config.ts`を変更する必要はありません。

### アカウントにサインイン

ブラウザをリフレッシュし、画面右上の`Connect`をクリックして、ポップアップ(ウォレットディスカバリー画面)でServiceAccountを選択します。

![スクリーンショット 2024-12-29 16.17.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/b9edf0a1-e776-2522-531a-55b0d80a55cc.png)

画面右上の`Connect`部分がアカウント表示に変わります。

![スクリーンショット 2024-12-29 16.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/d4b7e35c-31ee-8be4-fb7b-7217f7490859.png)

### Scriptコードの修正

この状態でブロックチェーンのエミュレータ・ネットワークとやり取りして、データを取得したり、変更したりするのですが、現時点ではエラーになります。画面下部に見える`Get greeting`ボタンをクリックします。
VSCodeのTerminalウィンドウで`flow emulator -v`を実行していた場所には以下のようにエラーが出力されます。

Output:
```ruby
4:19PM WRN ❗  Script reverted                           computationUsed=0 memoryEstimate=5618 scriptID=74835c241cf982db9066fdb1b61714490a8062423963bfd12bbc0ac5c50318e9
4:19PM WRN ERR [74835c] [Error Code: 1101] error caused by: 1 error occurred:
        * [Error Code: 1101] cadence runtime error: Execution failed:
error: `pub` is no longer a valid access keyword
 --> 74835c241cf982db9066fdb1b61714490a8062423963bfd12bbc0ac5c50318e9:3:0
  |
3 | pub fun main(): String {
  | ^^^

```

そのため、上記エラー内容をヒントに、これをv1.0に対応した状態に修正します。
`src/lib/flow/cadence/scripts/getGreeting.cdc`を開くと以下のようにVSCode のExtentionが修正すべきところに赤の波線を表示しています。
![スクリーンショット 2024-12-29 16.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/5973718a-312a-5318-0852-4ed4514a7664.png)

これを以下のように修正します。
```ruby
import "HelloWorld"

access(all) fun main(): String {
  return HelloWorld.greeting
}
```
これでもう一度画面下部の`Get greeting`ボタンを押します。

アプリの画面に以下が表示されます。
```ruby
Current Greeting: Hello, World!
```

:::note warn
💡もし、エミュレータを再起動している場合は、`flow project deploy`コマンドを再び実行して、エミュレータ上にスマートコントラクトを再度デプロイする必要があります。
:::

### Transactionコードの修正

1. 画面上部の「1. Change your Greeting」のテキストボックスに"Googbye, World!"と入力します。
1. `Change greeting`ボタンをクリックします。

以下のポップアップが画面上に表示されます。

![スクリーンショット 2024-12-30 7.03.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/73d52e2c-94d3-c29d-003d-41c9ae3b3658.png)

これはトランザクションの詳細を示しています。トランザクションはブロックチェーンのStateを変更する処理です。そのため提案者、支払者、承認者の３つの承認関数が必要ですが、このようにウォレットが代わりに用意してくれます<sup> (詳しくは[Day4](https://qiita.com/flowcadence/items/27ef976c2f2493146dd6)で解説します) </sup>。

あとは承認者であるあなたがAPPROVEボタンを押すと、ウォレットのアカウント鍵を使用してトランザクションが送信され、スマートコントラクトのState変数の値が書き換えられます。

ポップアップの中を下にスクロールすると、実際に行うトランザクションコードが表示されます。

![スクリーンショット 2024-12-30 7.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/536635b1-7ff5-3fb1-dd5e-8ce367b48c99.png)

Approve(承認)することによって`signer: AuthAccount`がトランザクションコードの引数に渡されます。この`signer`はアカウントのストレージに保存されたリソースやスマートコントラクト、鍵にアクセスすることができます。

`APPROVE`ボタンをクリックします。

Output
```ruby
7:12AM DBG ✉️   Transaction submitted                   txID=13a708134d10b3143fefd9f161798136968351ab71c05302597fde499a2f13c9
7:12AM WRN ❗  Transaction reverted                      computationUsed=0 memoryEstimate=20001 txID=13a708134d10b3143fefd9f161798136968351ab71c05302597fde499a2f13c9
7:12AM WRN ERR [13a708] [Error Code: 1101] error caused by: 1 error occurred:
        * transaction preprocess failed: [Error Code: 1101] cadence runtime error: Execution failed:
error: cannot find type in this scope: `AuthAccount`
 --> 13a708134d10b3143fefd9f161798136968351ab71c05302597fde499a2f13c9:4:18
  |
4 |   prepare(signer: AuthAccount) {
  |                   ^^^^^^^^^^^ not found in this scope
```
エラーになりました。これは`AuthAccount`がもうv1.0では使用できないからです。


`src/lib/flow/cadence/transactions/changeGreeting.cdc`を開くと以下のようにVSCode のExtentionが修正すべき箇所を赤の波線で表示してくれます。

![スクリーンショット 2024-12-30 7.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/8fcc3877-5824-b481-8f92-c533ca0eed07.png)

これを以下のように修正します。
```ruby
import "HelloWorld"

transaction(newGreeting: String) {
  prepare(signer: &Account) {

  }

  execute {
    HelloWorld.changeGreeting(newGreeting: newGreeting)
  }
}
```

1. 再度、画面上部の「1. Change your Greeting」テキストボックスに"`Googbye, World!`"と入力します。
1. `Change greeting`ボタンをクリックします。
1. `APPROVE`ボタンをクリックします。

画面右のアイコンがSealedに変われば成功です。
![スクリーンショット 2024-12-30 7.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/eb93d6f3-d0c6-a10f-9a47-859ab1243ce7.png)


こちらのWebアプリは非常によくできているので、私は`git clone`して動作を見てみると大変勉強になると思い、今回記事にしました。こちらのWebアプリは以下のYouTubeで動きを確認することが出来ます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/plkPyQx-H3U?si=SoDvBrG_3BDVvtC4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


***
<b>[Previous << 1 - 基本編Part1](https://qiita.com/flowcadence/items/8cc25249cda37364cac1)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95)

<b>[Next >> 3 - 基本編Part3](https://qiita.com/flowcadence/items/2911220eb06a20beea14)</b>

<h3>脚注</h3>

<sup>1: ユーザーの負担を和らげる方法に関しては手段が複数あり、Capabilityを他のアカウントに譲渡できる[Inbox](https://qiita.com/flowcadence/items/db88a071c732f68cc7fb)を使い、ユーザーに代わってトランザクション実行することや、Cadenceコアエンジニアによって開発された[Storefront](https://qiita.com/flowcadence/items/93a05e653883a93b617a)コアコントラクトも参考になってきます。</sup>

<sup>2: NFTのWebサイト(下記)にあるように**NFT**はCryptoKittiesを開発したDieter Shirleyによって考案・設計・実装されました。イーサリアムと違い、Dieter Shirley開発の**Flow blockchain**ではそのリソースを通じて好きなメソッドを呼ぶことが可能です。</sup>

https://ethereum.org/en/developers/docs/standards/tokens/erc-721/

https://eips.ethereum.org/EIPS/eip-721