SolanaプログラムにGIFカウンターを実装しよう!
今のところ、作成したプログラムでは何も起こりません。
データを保存するための変更を加えていきましょう!
今回作成するWebアプリケーションは、誰でもGIFを投稿することができます。
そのため、total_gifsでGIFの投稿数の管理ができるとかなり便利です。
🥞 GIF カウントを保存する
GIFの投稿数を保存するための変数total_gifsを定義し、誰かが新しくGIFを投稿した際に、total_gifsの数値を+1すれば良いだけです。
しかし、SolanaはEthereumと は異なり、「ステートレス」であるため、データを永久に保持することはできません。
ただし、Solanaは「アカウント」とやり取りができます。
Solanaの「アカウント」は「プログラムが読み書きできるファイル」のことを指します。
「ウォレットでアカウントを作成する」といった際に利用される「アカウント」とは異なるので、紛らわしいですが注意しましょう。
アカウントについての詳細はこちらを参照してください。
それでは、lib.rsを以下のとおり修正していきましょう。
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod myepicproject {
use super::*;
pub fn start_stuff_off(ctx: Context<StartStuffOff>) -> Result <()> {
// アカウントへのリファレンスを取得します。
let base_account = &mut ctx.accounts.base_account;
// total_gifsを初期化します。
base_account.total_gifs = 0;
Ok(())
}
}
// StartStuffOffコンテキストに特定の変数をアタッチします。
#[derive(Accounts)]
pub struct StartStuffOff<'info> {
#[account(init, payer = user, space = 9000)]
pub base_account: Account<'info, BaseAccount>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program <'info, System>,
}
// 指定のアカウントに何を保存したいかをSolanaに伝えます。
#[account]
pub struct BaseAccount {
pub total_gifs: u64,
}
以下でコードの中身を詳しく説明していきます。
🤠 アカウントを初期化する
#[account]
pub struct BaseAccount {
pub total_gifs: u64,
}
ここでは、どんな種類のアカウントを作成し、その中に何を保持するかを定義しています。
今回はBaseAccountがtotal_gifsという名前の整数を保持することになります。
#[derive(Accounts)]
pub struct StartStuffOff<'info> {
#[account(init, payer = user, space = 9000)]
pub base_account: Account<'info, BaseAccount>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program <'info, System>,
}
ここでは、StartStuffOffコンテキストで初期化する方法と保持する変数を実際に実際に指定しています。
[account(init, payer = user, space = 9000)]では、BaseAccountの初期化方法をSolanaに指示しています。
詳細は以下のとおりです。
1. initでは、Solanaにプログラムの新しいアカウントを作成するよう指示しています。
2. payer = userでは、アカウントの利用料金を誰が支払うかをプログラム側に指示しています(今回はこの関数を呼び出したユーザーです)。
3. space = 9000では、9000バイトのスペースがアカウントに割り当てています(今回は9000バイトで十分です)。
なぜアカウントにお金を支払う必要があるのでしょうか?
実は、データの保存は無料ではないのです。
Solanaの仕組み上、ユーザーがアカウントの「レンタル料」を支払う必要があります。
ちなみに、「レンタル料」を支払わない場合は、バリデータのよってアカウントが削除されます。
これらの詳細についてはこちらを参照してください。
pub user:Signer <'info> はプログラムに渡されるデータで、プログラムを呼び出したユーザーが、ウォレットアカウントを所有していることを証明するものです。
pub system_program:ProgramはSolanaを実行するプログラムSystemProgramへの参照です。
SystemProgramでは多くのことができますが、主な役割はSolanaアカウントを作成することです。
pub fn start_stuff_off(ctx: Context<StartStuffOff>) -> Result <()> {
// アカウントへのリファレンスを取得します。
let base_account = &mut ctx.accounts.base_account;
// total_gifsを初期化します。
base_account.total_gifs = 0;
Ok(())
}
最後に、start_stuff_off関数内でContext<StartStuffOff>を実行して、StartStuffOffコンテキストからbase_accountを取得する処理を実行します。