導入
これまでのレッスンでは「すでに存在するデータアカウント」を前提に読み書きしてきましたが、実際にはそのアカウント自体を最初に作る処理が必要です。アカウントの新規作成を担当するのは、Solana に最初から組み込まれている System Program です。ここでは PDA を CPI 経由で初期化する、実践的な流れをまとめて見ていきます。
説明
新しいアカウントを作る命令は system_instruction::create_account で組み立てます。
use solana_program::{
account_info::AccountInfo,
program::invoke_signed,
pubkey::Pubkey,
rent::Rent,
sysvar::Sysvar,
system_instruction,
entrypoint::ProgramResult,
};
fn create_vault_pda(
program_id: &Pubkey,
payer: &AccountInfo, // 作成コストを支払うアカウント(ユーザー)
vault_pda: &AccountInfo, // これから作るPDA本体
system_program: &AccountInfo,
bump: u8,
) -> ProgramResult {
let space: u64 = 41; // VaultAccount(owner:32 + balance:8 + bump:1)のバイト数
let rent = Rent::get()?;
let lamports = rent.minimum_balance(space as usize); // レント免除に必要な最低残高
let seeds: &[&[u8]] = &[b"vault", payer.key.as_ref(), &[bump]];
invoke_signed(
&system_instruction::create_account(
payer.key, // 支払い元
vault_pda.key, // 作成するアカウント(PDA)
lamports, // 入れておく初期SOL(レント免除分)
space, // 確保するデータ領域のバイト数
program_id, // このアカウントの所有者を自分のプログラムにする
),
&[payer.clone(), vault_pda.clone(), system_program.clone()],
&[seeds], // PDAの代理署名に使うseeds
)?;
Ok(())
}
flowchart TD
A["ユーザーが初期化命令を送る<br/>(payer + vault PDA + system_program)"] --> B["find_program_addressでPDAとbumpを確認"]
B --> C["Rent::get()でレント免除の必要残高を計算"]
C --> D["system_instruction::create_accountを組み立て"]
D --> E["invoke_signedでPDAの代理署名つきで実行"]
E --> F["System Programがアカウントを作成<br/>ownerを自分のプログラムに設定"]
F --> G["以後、このPDAにVaultAccountを読み書きできる"]
ポイントは、PDA 自身に秘密鍵がないため、PDA を作成する命令に対して「PDA からの署名」を用意できないということです。その代わりに、invoke_signed へ導出時と同じ seeds(と bump)を渡すことで、Solana ランタイムが「このプログラムはこの PDA を正しく導出できる=所有者として振る舞ってよい」と認め、代理署名として扱ってくれます。
ここまで見てきたとおり、ネイティブなプログラムでは「命令のデシリアライズ」「署名者・所有者チェック」「PDA の導出」「レント免除額の計算」「create_account の組み立て」といった定型的な手続きを、機能を作るたびに手で書く必要があります。この繰り返しの多さこそが、次章で学ぶ Anchor フレームワークが解決しようとしている課題です。Anchor では、こうした定型コードの大部分をマクロと属性(アトリビュート)が肩代わりしてくれます。
演習
この章で出てきた「PDAの作成」の一連の手順(find_program_address → レント免除額の計算 → create_account → invoke_signed)を、自分の言葉で1つずつ箇条書きにまとめてみましょう。次章で Anchor がどの手順を自動化してくれるか、比較しながら読み進める準備になります。
ヒント1を見る
手順は「アドレスを決める」「必要なSOLを計算する」「アカウント作成命令を組み立てる」「代理署名つきで実行する」の4段階に分けられます。
ヒント2を見る
このうちどれか1つでも欠けると、アカウントが作れない・作れても壊れた状態になる、とイメージすると理解が深まります。