PDA imzalayıcıları olmayan CPI'lar

Özet

Tüm gerekli imzalayıcıların orijinal işlemi zaten imzaladığı CPI'lar için invoke kullanın. PDA imzalama gerekmez. İmzalayıcı ve yazılabilir ayrıcalıklar çağıran programdan çağrılan programa uzanır.

PDA imzalayıcıları olmayan CPI'lar

Bir CPI PDA imzalayıcıları gerektirmediğinde, invoke fonksiyonu kullanılır. invoke fonksiyonu, boş bir signers_seeds dizisi ile invoke_signed fonksiyonunu çağırır. Boş imzalayıcılar dizisi, imzalama için hiçbir PDA'nın gerekli olmadığını gösterir.

Invoke function
pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
invoke_signed(instruction, account_infos, &[])
}

Aşağıdaki örnekler Anchor ve Native Rust kullanarak bir CPI yapar. Bir hesaptan diğerine SOL transfer eden tek bir talimat içerir.

Anchor

Aşağıdaki örnekler, bir Anchor programında CPI'ları uygulamanın iki yaklaşımını gösterir. Örnekler işlevsel olarak eşdeğerdir, ancak farklı soyutlama seviyelerini gösterir.

  • Örnek 1: Anchor'ın CpiContext ve yardımcı fonksiyonunu kullanır.
  • Örnek 2: solana_program crate'inden system_instruction::transfer fonksiyonunu kullanır.
  • Örnek 3: CPI talimatını manuel olarak oluşturur. Bu yaklaşım, çağırmak istediğiniz talimatı oluşturmaya yardımcı olacak bir crate olmadığında kullanışlıdır.
use anchor_lang::prelude::*;
use anchor_lang::system_program::{transfer, Transfer};
declare_id!("9AvUNHjxscdkiKQ8tUn12QCMXtcnbR9BVGq3ULNzFMRi");
#[program]
pub mod cpi {
use super::*;
pub fn sol_transfer(ctx: Context<SolTransfer>, amount: u64) -> Result<()> {
let from_pubkey = ctx.accounts.sender.to_account_info();
let to_pubkey = ctx.accounts.recipient.to_account_info();
let program_id = ctx.accounts.system_program.to_account_info();
let cpi_context = CpiContext::new(
program_id,
Transfer {
from: from_pubkey,
to: to_pubkey,
},
);
transfer(cpi_context, amount)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct SolTransfer<'info> {
#[account(mut)]
sender: Signer<'info>,
#[account(mut)]
recipient: SystemAccount<'info>,
system_program: Program<'info, System>,
}

Rust

Aşağıdaki örnek, Native Rust ile yazılmış bir programdan nasıl CPI yapılacağını gösterir. Bir hesaptan diğerine SOL transfer eden tek bir talimat içerir. (Test dosyası programı test etmek için LiteSVM kullanır.)

use borsh::BorshDeserialize;
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
program::invoke,
program_error::ProgramError,
pubkey::Pubkey,
system_instruction,
};
// Declare program entrypoint
entrypoint!(process_instruction);
// Define program instructions
#[derive(BorshDeserialize)]
enum ProgramInstruction {
SolTransfer { amount: u64 },
}
impl ProgramInstruction {
fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
Self::try_from_slice(input).map_err(|_| ProgramError::InvalidInstructionData)
}
}
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
// Deserialize instruction data
let instruction = ProgramInstruction::unpack(instruction_data)?;
// Process instruction
match instruction {
ProgramInstruction::SolTransfer { amount } => {
// Parse accounts
let [sender_info, recipient_info, system_program_info] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};
// Verify the sender is a signer
if !sender_info.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
// Create and invoke the transfer instruction
let transfer_ix = system_instruction::transfer(
sender_info.key,
recipient_info.key,
amount,
);
invoke(
&transfer_ix,
&[
sender_info.clone(),
recipient_info.clone(),
system_program_info.clone(),
],
)?;
Ok(())
}
}
}

Is this page helpful?

İçindekiler

Sayfayı Düzenle

Yönetici

© 2026 Solana Vakfı.
Tüm hakları saklıdır.
Bağlanın