クロスプログラム呼び出し
このセクションでは、前のPDAセクションのCRUDプログラムが、Solanaプログラムが互いに呼び出すことを可能にする機能であるクロスプログラム呼び出し(CPI)を追加することで更新されます。
このチュートリアルでは、プログラムがクロスプログラム呼び出しを行う際にプログラム派生アドレス(PDA)に対して「署名」する方法も示しています。
update
とdelete
命令は、System
Programを呼び出すことによってアカウント間のSOL転送を処理するために修正が必要です。
このセクションの目的には、Anchorフレームワークを使用してSolanaプログラムでCPIを実装するプロセスを説明し、前のセクションで探求したPDAの概念を基に構築することが含まれます。詳細については、クロスプログラム呼び出しページを参照してください。
参考として、このリンクにはPDAとCPIの両方のセクションを完了した後の最終コードが含まれています。
このセクションのスターターコードには、PDAセクションのみが完了しています。
更新命令の更新
まず、プログラムは*rsUpdate
*構造体とupdate
関数を変更することで、シンプルな「更新のための支払い」メカニズムを必要とします。
system_program
モジュールからアイテムをスコープに取り込むために、lib.rs
ファイルの更新から始めます。
use anchor_lang::system_program::{transfer, Transfer};
次に、*rsUpdate
*構造体を更新して、vault_account
という新しいアカウントを含めます。このアカウントはプログラムによって制御され、ユーザーがメッセージアカウントを更新する際にユーザーからSOLを受け取ります。
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
次に、update
命令にCPIロジックを追加して、ユーザーのアカウントからボールトアカウントに0.001
SOLを転送します。
let transfer_accounts = Transfer {from: ctx.accounts.user.to_account_info(),to: ctx.accounts.vault_account.to_account_info(),};let cpi_context = CpiContext::new(ctx.accounts.system_program.to_account_info(),transfer_accounts,);transfer(cpi_context, 1_000_000)?;
プログラムを再ビルドします。
$build
削除命令の更新
*rsDelete
*構造体とdelete
関数を変更して、「削除時の返金」メカニズムを追加します。
まず、*rsDelete
*構造体を更新してvault_account
を含めます。これにより、ユーザーがメッセージアカウントを閉じるときにボールト内のSOLをユーザーに返金することができます。
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
また、転送のCPIにはSystem
Programの呼び出しが必要なため、system_program
も追加します。
pub system_program: Program<'info, System>,
次に、delete
命令にCPIロジックを追加して、ボールトアカウントからユーザーのアカウントにSOLを転送します。
let user_key = ctx.accounts.user.key();let signer_seeds: &[&[&[u8]]] =&[&[b"vault", user_key.as_ref(), &[ctx.bumps.vault_account]]];let transfer_accounts = Transfer {from: ctx.accounts.vault_account.to_account_info(),to: ctx.accounts.user.to_account_info(),};let cpi_context = CpiContext::new(ctx.accounts.system_program.to_account_info(),transfer_accounts,).with_signer(signer_seeds);transfer(cpi_context, ctx.accounts.vault_account.lamports())?;
*rs_ctx: Context<Delete>
がrsctx: Context<Delete>
*に変更され、関数本体でコンテキストを使用することに注意してください。
プログラムを再ビルドします。
$build
プログラムの再デプロイ
これらの変更を行った後、更新されたプログラムを再デプロイします。これにより、変更されたプログラムがテスト可能になります。Solanaでは、プログラムの更新は単に同じプログラムIDでプログラムをデプロイするだけです。
PlaygroundウォレットにdevnetのSOLがあることを確認してください。Solana Faucetからdevnet SOLを取得できます。
$deploy
テストファイルの更新
次に、anchor.test.ts
ファイルを更新して、命令に新しいボールトアカウントを含めます。これには、ボールトPDAを導出し、更新および削除命令の呼び出しに含める必要があります。
Vault PDAの導出
まず、vault PDAの導出を追加します:
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync([Buffer.from("vault"), wallet.publicKey.toBuffer()],program.programId);
Updateテストの変更
次に、vaultAccount
を含めるようにupdate命令を更新します
const transactionSignature = await program.methods.update(message).accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Deleteテストの変更
次に、vaultAccount
を含めるようにdelete命令を更新します
const transactionSignature = await program.methods.delete().accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
次のステップ
Solanaクイックスタートガイドを完了おめでとうございます。以下のSolanaの重要な概念について実践的な経験を得ることができました:
- アカウントからのデータの取得と読み取り
- トランザクションの構築と送信
- Solanaプログラムのデプロイと更新
- Program Derived Addresses (PDAs)の操作
- Cross-Program Invocations (CPIs)の実行
これらの概念についての理解を深めるには、コア概念のドキュメントをチェックしてください。このガイドで取り上げたトピックについて詳細な説明が提供されています。
さらなる例を探索する
例から学ぶことを好む場合は、プログラム例リポジトリをチェックして、様々なサンプルプログラムを確認してください。
Solana Playgroundには、GitHubリンクを使用してプロジェクトをインポートまたは表示できる便利な機能があります。例えば、このSolana Playgroundリンクを開くと、このGithubリポジトリからAnchorプロジェクトを表示できます。
Import
ボタンをクリックし、プロジェクト名を入力して、Solana
Playgroundのプロジェクトリストに追加します。プロジェクトがインポートされると、すべての変更は自動的に保存され、永続化されます。
Is this page helpful?