見出し画像

【完全保存版】SolanaでMetaplexを使ったゲームプログラムを作ってみよう!

この記事は、こちらのプログラムの解説を行っています。

ドラクエで敵を倒すようなゲームです。

なお、実行時に、この部分をご自身のアドレスにする必要がありますので、ご注意ください。

1 ミントアカウント作成に必要なアカウント

まずはミントアカウントを作成する「createMint」必要なアカウントを見てみましょう。

1 管理者アカウント

まず、管理者アカウントが必要です。

「Signer」となっているので署名者です。

まだ、addressの制約が入っています。

事前に設定している、「ADMIN_PUBKEY」と一致しているかのチェックが行われます。

https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html

2 報酬用のミントアドレス

次は、報酬用のミントアドレスです。

seeds = [b"reward"]が設定されているので、PDAです。

ちなみに、「mint::decimals」「mint::authority」が設定されています。

こちらで桁数権限者チェック、もしくは作成する場合の情報として使っています。

https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html

3 ミントアカウントのメタデータ

そして、ミントアカウントのメタデータも設定しています。

「address=」でアドレスの指定を行っています。

では、どのアドレスを指定しているのか、「find_metadata_account」関数を見てみましょう。

中身は、こちらの「Pubkey」に実装されている、「find_program_address」という関数でした。

シードプログラムIDを指定して、PDAを見つけてくれます。

https://docs.rs/solana-program/latest/solana_program/pubkey/struct.Pubkey.html

ここはとても大事なところだと思いますが。

Metaplexメタデータアカウントに使われるシードが確認できます。

このようになっています。

ちなみに、具体的なIDはこちらから確認ができます。

https://docs.rs/mpl-token-metadata/latest/src/mpl_token_metadata/generated/programs.rs.html#11

そして、最後にプログラムIDを設定していますね。

2 ミントアカウントの作成

では、具体的に「create_mint」関数を見てみましょう。

1 シード等の取得

まずは、PDAに必要なシード、バンプ、署名者を取得しています。

2 データの設定

次に、dataは「DataV2」の型が必要です。

こちらは後に出てくる、「create_metadata_accounts_v3」がデータとして、「DataV2」の型を求めているためです。

こちらを使用しています。

https://docs.rs/mpl-token-metadata/4.1.2/mpl_token_metadata/types/struct.DataV2.html

3 CpiContextの作成

次に、CpiContextを作成しています。

今回は呼び出しもとが「報酬用ミントアカウント」であり、PDAなので「new_with_signer」を使用しています。

また、アカウントとしては「createMetadataAccountsV3」を使用しています。

これによって、CpiContextの型を「CreateMetadataAccountsV3」にしています。

その名の通り、メタデータアカウントを作りたいのですね。

ちなみに、こちらもご参照ください。

https://docs.rs/anchor-spl/latest/anchor_spl/metadata/struct.CreateMetadataAccountsV3.html

4 メタデータアカウントの作成

これで、準備ができたので、「create_metadata_accounts_v3」でメタデータを作成します。

なお、ここで指定する「cpi_context」「CreateMetadataAccountsV3」の型である必要があります。

dataは「DataV2」の型である必要があります。

ドキュメントはこちらです。

https://docs.rs/anchor-spl/latest/anchor_spl/metadata/fn.create_metadata_accounts_v3.html

3 プレイヤーの初期化

では他の関数も見てみましょう。

こちらの「init_player」でプレイヤーの体力を全快にしています。

ちなみに、「player_data」というアカウントは「player」という文字列「playerの公開鍵」の2つのシードを取るPDAです。

そして、「health」という値を持っています。

4 敵の撃退

次に敵を撃退する関数を見てみましょう。

0 概要

この関数の概要は、まず体力チェックを行い、0になっていないかを確認します。

その上で、体力を10減らし報酬用トークンを配布します。

1 体力のチェック

まずは体力をチェックし、0であれば、エラーを返しています。

2 体力の削減

次に、「checked_sub()」を使って、体力を10減らしています。

きっと戦ったからですね。

ちなみに、「checked_sub」はアンダーフローを監視してくれます。

もしアンダーフローになった場合は、Noneを返します。

https://docs.rs/num/latest/num/trait.CheckedSub.html#tymethod.checked_sub

3 トークンのミント準備① シード等の取得

後に、PDAによるCPIを実行したいので、シードなどの必要なものを取得しています。

今回は報酬用ミントアカウント用のシードなどを取得しています。

4 トークンのミント準備② CpiContextの作成

下のようにして、CpiContextを作成しています。

PDAによる実行なので、「new_with_signer」を使います。

このCpiContextミント用なので、アカウントは「MintTo」という型を使用しています。

ドキュメントはこちらです。

https://docs.rs/anchor-spl/latest/anchor_spl/token/struct.MintTo.html

5 ミント量の設定

では、ミント量も設定しましょう。

「1トークン」なのですが、最小単位(10の9乗など)をかけてあげる必要があります。

下のようにして、「u64」の型の1に10の桁数乗をかけています。

「checked_mul」でオーバーフロー、もしくはアンダーフローのチェックを行っています。

「pow」では◯乗の部分を設定しています。

例の2の5乗が32になっているのがわかりやすいですね。

https://doc.rust-lang.org/std/primitive.u64.html#method.pow

6 ミントの実行

最後に、「mint_to」でミントを実行しています。

こちらのドキュメントのように、「MintTo」の型のCpiContextamountを設定しています。

https://docs.rs/anchor-spl/latest/anchor_spl/token/fn.mint_to.html

5 回復

次に、回復を行う関数を見てみましょう。

0 概要

この関数の流れとしては、2つです。

まず、体力を全回復させます。

その上で、トークンをバーンさせます。

このトークンはドラクエで言うところの「世界樹のしずく」みたいなものでしょうか。(最もキャラクターは1人ですが。)

1 回復

プレイヤーの体力をマックスにしています。

2 トークンのバーン準備 CpiContextの作成

下のようにして、「Burn」 の型の「CpiContext」を作成しています。

先ほどの、「new_with_signer」でないのは、実行するのがPDAではなく、署名者だからです。

自分が持っているトークンをバーンします。

3 バーン量の設定

これは、敵の撃退の時と同じですね。

「checked_mul」オーバーフローアンダーフローをチェックしています。

「pow」では10の◯乗を設定しています。

4 バーンの実行

最後に、CpiContextamountを使って、バーンをしています。

こちらが、バーンですが、「mint_to」と基本同じですね。

https://docs.rs/anchor-spl/latest/anchor_spl/token/fn.burn.html


説明は以上となります。

よかったらやってみてください。




サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊