pub fn transfer_many(
from_pubkey: &Pubkey,
to_lamports: &[(Pubkey, u64)],
) -> Vec<Instruction>
Expand description
Transfer lamports from an account owned by the system program to multiple accounts.
This function produces a vector of Instruction
s which must be submitted
in a Transaction
or invoked to take effect, containing serialized
SystemInstruction::Transfer
s.
§Required signers
The from_pubkey
signer must sign the transaction.
§Examples
§Example: client-side RPC
This example performs multiple transfers in a single transaction.
use solana_rpc_client::rpc_client::RpcClient;
use solana_sdk::{
pubkey::Pubkey,
signature::{Keypair, Signer},
system_instruction,
transaction::Transaction,
};
use anyhow::Result;
fn transfer_lamports_to_many(
client: &RpcClient,
from: &Keypair,
to_and_amount: &[(Pubkey, u64)],
) -> Result<()> {
let instrs = system_instruction::transfer_many(&from.pubkey(), to_and_amount);
let blockhash = client.get_latest_blockhash()?;
let tx = Transaction::new_signed_with_payer(
&instrs,
Some(&from.pubkey()),
&[from],
blockhash,
);
let _sig = client.send_and_confirm_transaction(&tx)?;
Ok(())
}
§Example: on-chain program
This example makes multiple transfers out of a “bank” account,
a program derived address owned by the calling program.
This example submits the instructions from an on-chain Solana program. The
created account is a program derived address, and it is assigned to
the running program. The payer
and new_account_pda
are signers, with
new_account_pda
being signed for virtually by the program itself via
invoke_signed
, payer
being signed for by the client that submitted the
transaction.
use solana_program::{
account_info::{next_account_info, next_account_infos, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
msg,
program::invoke_signed,
pubkey::Pubkey,
system_instruction,
system_program,
};
/// # Accounts
///
/// - 0: bank_pda - writable
/// - 1: system_program - executable
/// - *: to - writable
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct TransferLamportsToManyInstruction {
pub bank_pda_bump_seed: u8,
pub amount_list: Vec<u64>,
}
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let instr = TransferLamportsToManyInstruction::deserialize(&mut &instruction_data[..])?;
let account_info_iter = &mut accounts.iter();
let bank_pda = next_account_info(account_info_iter)?;
let bank_pda_bump_seed = instr.bank_pda_bump_seed;
let system_account = next_account_info(account_info_iter)?;
assert!(system_program::check_id(system_account.key));
let to_accounts = next_account_infos(account_info_iter, account_info_iter.len())?;
for to_account in to_accounts {
assert!(to_account.is_writable);
// ... do other verification ...
}
let to_and_amount = to_accounts
.iter()
.zip(instr.amount_list.iter())
.map(|(to, amount)| (*to.key, *amount))
.collect::<Vec<(Pubkey, u64)>>();
let instrs = system_instruction::transfer_many(bank_pda.key, to_and_amount.as_ref());
for instr in instrs {
invoke_signed(&instr, accounts, &[&[b"bank", &[bank_pda_bump_seed]]])?;
}
Ok(())
}