0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ブロックチェーンゲームの作り方5 所持金表示

Last updated at Posted at 2025-01-01

Previous << 4 - 基本編Part4
Next >> 6 - プレイヤー登録

リソースから情報を取り出す

前回話した通り、所持金のResourceはアカウントを作成した時から持っています。最低限のお金もアカウント作成者が負担してくれます。

この最低限のお金はアカウントストレージのデポジット費用だと思ってください。この最低限の所持金は引き出す事ができませんが、その代わりに用意されたストレージを自由に使うことができます。

この所持金の残高を取得するにはCapabilityを使用します。Capabilityって何?という方はDay3を読んでみてください。

Capabilityはアカウントストレージにあるリソースのメソッドを誰でも呼べるように公開したものですから、FCLを使っていつでも呼び出すことができます。

Why Flow

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

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

💡もし、エミュレータの起動方法やスマートコントラクトのデプロイについて操作に自信がない場合はこちらを参照してください。

スマートコントラクトでゲームを作る

Day3で作ったHelloWorldスマートコントラクトを修正してゲームを作成していきます。
まず、所持金を表示します。

このゲームではFungibleTokenFlowTokenをインポートしますので、ここを参考に依存関係をflow.jsonにインストールします。

flow dependencies install FlowToken FungibleToken 

こうすることで、flow.jsonの"dependencies"には以下が追加されます。

		"FlowToken": {
			"source": "mainnet://1654653399040a61.FlowToken",
			"hash": "cefb25fd19d9fc80ce02896267eb6157a6b0df7b1935caa8641421fe34c0e67a",
			"aliases": {
				"emulator": "0ae53cb6e3f42a79",
				"mainnet": "1654653399040a61",
				"testnet": "7e60df042a9c0868"
			}
		},
		"FungibleToken": {
			"source": "mainnet://f233dcee88fe0abe.FungibleToken",
			"hash": "050328d01c6cde307fbe14960632666848d9b7ea4fef03ca8c0bbfb0f2884068",
			"aliases": {
				"emulator": "ee82856bf20e2aa6",
				"mainnet": "f233dcee88fe0abe",
				"testnet": "9a0766d93b6608b7"
			}
		},

何故ゲームなのか

スマートコントラクトはまだ一般人には馴染みが薄いですが、ゲームであれば一般人にも受け入れられやすいからです。

全てのアカウントは、初期状態で最低限のFlowTokenを持っています。これはストレージの費用として最低0.001Flowを持つこと、としているためです。ただし、実際には支払うことはありません。

以下がFlowToken所持金を取得するスクリプトです。

get_balance.cdc
import "FlowToken"
import "FungibleToken"

access(all) fun main(address: Address): UFix64 {
  let vaultRef = getAccount(address).capabilities
      .borrow<&FlowToken.Vault>(/public/flowTokenBalance)
    ?? panic("Something wrong happened.")
  return vaultRef.balance
}

このスクリプトをFlow CLIで実行します。

flow scripts execute ./get_balance.cdc "0xf8d6e0586b0a20c7"

0xf8d6e0586b0a20c7の部分は開発で使用しているエミュレータアカウントのアドレスであり、flow.jsonの以下の部分です。

	"accounts": {
		"emulator-account": {
			"address": "f8d6e0586b0a20c7",
			"key": {
				"type": "file",
				"location": "emulator-account.pkey"
			}
		}
	},

Output:

Result: 999999999.99600000

FlowTokenは十分あるようです。テストネットみたいに追加できないのであらかじめ豊富に用意されているようです。

このFlow Tokenを使ってゲームをしていきます。そのため、このFLOW残高は画面のわかりやすいところに表示する必要があります。

Webフレームワークを準備

ウォレットを表示するためにはWebフレームワークが必要なので、私はSvelteをインストールしました。(Svelteが1番簡単です)プロジェクト名はawesome-cardgameとしました。

npx sv create awesome-cardgame

awesome-cardgameのフォルダに入ってnpm run devを実行すると、http://localhost:5173/に初期画面が表示されます。

次に、必要なライブラリをインストールします。

npm install --save @onflow/fcl

Day1のプロジェクトからflow.jsonemulator-account.pkeyを、awesome-cardgameプロジェクトのsrcフォルダにコピーして以下コマンドを実行します:

flow emulator -v

Dev Walletを起動する

エミュレータが起動している状態で、以下コマンドを実行します。

flow dev-wallet

HTMLとロジックを書く

メイン画面のロジックを以下のようにします。

+page.svelte
<script>
  import { config, authenticate, unauthenticate, currentUser } from '@onflow/fcl';
  import { getBalance } from '../scripts';
  import flowJSON from '../flow.json';
  const network = 'emulator';
  let walletUser;
  let flowBalance;
  config({
    'flow.network': network,
    'accessNode.api': 'http://localhost:8888',
    'discovery.wallet': 'http://localhost:8701/fcl/authn',
  }).load({ flowJSON });
  currentUser.subscribe(async (user) => {
    walletUser = user;
    if (user.addr) {
      flowBalance = await getBalance(user.addr);
    }
  });
</script>
FLOW残高: {flowBalance}
<button onclick={authenticate}>ログイン</button>
<button onclick={unauthenticate}>ログアウト</button>

ログインとログアウトした時にcurrentUser.subscribeが呼び出されます。ログイン後はuser.addrがあり、ログアウト後はuser.addrがありません。user.addrがあればgetBalanceを実行します。

残高をjsで取得する

FlowToken所持金を取得するスクリプトの内容をjsで取得するには、以下のようにfcl.queryを使用します。

src/scripts.js
import { query } from "@onflow/fcl";

export const getBalance = async function (address) {
  const result = await query({
    cadence: `
    import "FlowToken"
    import "FungibleToken"

    access(all) fun main(address: Address): UFix64 {
      let vaultRef = getAccount(address).capabilities
          .borrow<&FlowToken.Vault>(/public/flowTokenBalance)
        ?? panic("Something wrong happened.")
      return vaultRef.balance
    }
    `,
    args: (arg, t) => [arg(address, t.Address)],
  });
  return result;
};

fcl設定で.load({ flowJSON })を追加している為、import "FlowToken"import FlowToken from 0x0ae53cb6e3f42a79に実行時に解決されます。

所持金を取得/表示する

これで所持金表示のロジックはすべて準備できましたので、http://localhost:5173/にアクセスします。

ログインボタンを押します。
スクリーンショット 2025-01-01 10.13.39.png

Service Accountを押すと一発でログインできます。アカウントはemulator-accountと同じです。

Service Accountを押します。以下のように画面一番左に残高を表示することが出来ます。

スクリーンショット 2025-01-01 10.16.55.png

ログイン済みですとウォレットログインのポップアップは出ませんのでご注意ください。


FlowではWallet Discoveryシステムが採用されています。イーサリアムのようにメタマスクをブラウザに登録する必要がなく、一貫した理念のもと、誰にでも触れやすいブロックチェーンアプリの構築が可能になっています。

他のブロックチェーンで開発をしたことがある人にとっては逆にとっつきにくいかも知れませんが、メタマスクを触ったことがない人にとってはこちらの方が非常に使いごこちがいいはずです(私もメタマスクより先にFlowのWallet Discoveryを経験したくちです)。

エミュレータには表示されませんが、テストネットやメインネットではウォレットはBloctoを選択するといいでしょう。BloctoはFlowローンチ時に作られた、やはり同じ理念のもと、ユーザーフレンドリーさが最優先されたウォレットであり、SDKなどもあります。

Wallet DiscoveryによるBloctoなどのウォレットログインはブラウザにウォレットをインストールする必要がない為、以前の形式のHTMLからでもウォレットを呼び出そうと思えば呼び出せます[1]。ですからゲーム機のNintendo SwitchやPlay Stationの中でもウォレットを呼び出せるのです(確かPS Vitaでブラウザ呼び出せたはず)。これは他のブロックチェーンにはできない、FlowのWallet DiscoveryシステムとBloctoウォレットが持つ大きな優位性です。

[1]: fcl-jsのNPMパッケージをES5以前のjsファイルにコンパイルすることで可能です。コンパイル手順はこちら


この記事のソースコードはこちらにあります。


Previous << 4 - 基本編Part4

Flow blockchain / Cadence version1.0ドキュメント

Next >> 6 - プレイヤー登録

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?