Pagamenti batch

Una transazione Solana è un contenitore che contiene una o più istruzioni. Ogni istruzione è un'operazione: trasferire token, creare un account, chiamare un programma. La rete esegue tutte le istruzioni in una transazione in modo sequenziale e atomico: o ogni istruzione ha successo, oppure l'intera transazione fallisce e viene annullata.

Questo significa che puoi raggruppare più trasferimenti in una singola transazione. Invece di inviare tre transazioni separate per pagare tre destinatari, invii una transazione con tre istruzioni di trasferimento. Questo è più veloce (una conferma invece di tre) e più economico (una commissione base invece di tre). Ecco un esempio illustrativo di come i pagamenti (chiamati "drops" in questa immagine) vengono raggruppati in una singola transazione e come vengono inviate più transazioni per gestire il batch più grande.

Diagramma pagamenti batchDiagramma pagamenti batch

Fonte: QuickNode - How to Send Bulk Transactions on Solana

Per maggiori informazioni su transazioni e istruzioni, consulta le guide Transazioni e Istruzioni.

La procedura seguente mostra come caricare più istruzioni di trasferimento in una singola transazione per i pagamenti batch.

Raggruppare istruzioni in una singola transazione

Una transazione Solana può contenere più trasferimenti verso destinatari diversi. Firmi una volta, paghi una commissione di transazione e tutti i trasferimenti vengono regolati insieme. Se un trasferimento fallisce, l'intera transazione viene rifiutata.

Consulta Come funzionano i pagamenti su Solana per i concetti fondamentali sui pagamenti.

Raggruppare più trasferimenti richiede la costruzione di ogni istruzione separatamente, per poi combinarle in una singola transazione.

I passaggi seguenti mostrano il flusso principale. Consulta la Demo per il codice completo eseguibile.

Derivare gli account token

Per prima cosa, deriva gli indirizzi degli associated token account (ATA) per il mittente e ciascun destinatario. Gli ATA sono indirizzi deterministici basati sul wallet e sul mint.

Creare le istruzioni di trasferimento

Crea un'istruzione di trasferimento separata per ciascun destinatario. Ogni istruzione specifica:

  • indirizzo del token account di origine
  • indirizzo del token account di destinazione
  • autorità (indirizzo del proprietario del token account di origine)
  • importo in unità base (adattato ai decimali del mint)

Inviare come singola transazione

Aggiungi tutte le istruzioni di trasferimento in un'unica transazione. Questo esegue tutti i trasferimenti in modo atomico: o tutti i trasferimenti hanno successo o l'intera transazione fallisce.

Verificare i saldi

Dopo il trasferimento batch, verifica i saldi dei token per tutte le parti utilizzando l'helper splToken.

Derivare gli account token

Per prima cosa, deriva gli indirizzi degli associated token account (ATA) per il mittente e ciascun destinatario. Gli ATA sono indirizzi deterministici basati sul wallet e sul mint.

Creare le istruzioni di trasferimento

Crea un'istruzione di trasferimento separata per ciascun destinatario. Ogni istruzione specifica:

  • indirizzo del token account di origine
  • indirizzo del token account di destinazione
  • autorità (indirizzo del proprietario del token account di origine)
  • importo in unità base (adattato ai decimali del mint)

Inviare come singola transazione

Aggiungi tutte le istruzioni di trasferimento in un'unica transazione. Questo esegue tutti i trasferimenti in modo atomico: o tutti i trasferimenti hanno successo o l'intera transazione fallisce.

Verificare i saldi

Dopo il trasferimento batch, verifica i saldi dei token per tutte le parti utilizzando l'helper splToken.

Batch Payments
const [senderAta] = await findAssociatedTokenPda({
mint: mint.address,
owner: sender.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
const [recipient1Ata] = await findAssociatedTokenPda({
mint: mint.address,
owner: recipient1.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
const [recipient2Ata] = await findAssociatedTokenPda({
mint: mint.address,
owner: recipient2.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});

Demo

Demo
// Generate keypairs for sender and two recipients
const sender = (await generateKeypair()).signer;
const recipient1 = (await generateKeypair()).signer;
const recipient2 = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Recipient 1 Address:", recipient1.address);
console.log("Recipient 2 Address:", recipient2.address);
// Demo Setup: Create client, mint account, token accounts, and fund with initial tokens
const { client, mint } = await demoSetup(sender, recipient1, recipient2);
console.log("\nMint Address:", mint.address);
// Derive the Associated Token Accounts addresses (ATAs) for sender and recipients
const [senderAta] = await findAssociatedTokenPda({
mint: mint.address,
owner: sender.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
const [recipient1Ata] = await findAssociatedTokenPda({
mint: mint.address,
owner: recipient1.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
const [recipient2Ata] = await findAssociatedTokenPda({
mint: mint.address,
owner: recipient2.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
console.log("Sender Token Account:", senderAta.toString());
console.log("Recipient 1 Token Account:", recipient1Ata.toString());
console.log("Recipient 2 Token Account:", recipient2Ata.toString());
// =============================================================================
// Batch Token Payment Demo
// =============================================================================
// Create instructions to transfer tokens from sender to both recipients
// Transferring 250,000 base units = 0.25 tokens (with 6 decimals) to each
const transfer1Instruction = getTransferInstruction({
source: senderAta,
destination: recipient1Ata,
authority: sender.address,
amount: 250_000n // 0.25 tokens
});
const transfer2Instruction = getTransferInstruction({
source: senderAta,
destination: recipient2Ata,
authority: sender.address,
amount: 250_000n // 0.25 tokens
});
// Prepare and send both transfers in a single transaction using @solana/client
const signature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [transfer1Instruction, transfer2Instruction],
version: 0
});
console.log("\n=== Batch Token Payment Complete ===");
console.log("Transaction Signature:", signature.toString());
// Fetch final token account balances using @solana/client SPL token helper
const splToken = client.splToken({
mint: mint.address,
tokenProgram: "auto"
});
const senderBalance = await splToken.fetchBalance(sender.address);
const recipient1Balance = await splToken.fetchBalance(recipient1.address);
const recipient2Balance = await splToken.fetchBalance(recipient2.address);
console.log("\nSender Token Account Balance:", senderBalance);
console.log("Recipient 1 Token Account Balance:", recipient1Balance);
console.log("Recipient 2 Token Account Balance:", recipient2Balance);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

Scalare con la pianificazione delle transazioni

Una singola transazione ha limiti di dimensione: circa 1232 byte. Per operazioni batch di grandi dimensioni (buste paga per centinaia di dipendenti, airdrop di massa), supererai questo limite e dovrai suddividere il lavoro su più transazioni.

Sebbene tu sia libero di creare la tua logica di distribuzione delle transazioni, il package @solana/instruction-plans (parte di Solana Kit) gestisce questo a due livelli:

I piani di istruzioni definiscono le tue operazioni e i loro vincoli di ordinamento:

  • Sequenziali — istruzioni che devono essere eseguite in ordine
  • Parallele — istruzioni che possono essere eseguite in qualsiasi ordine
  • Non divisibili — istruzioni che devono rimanere insieme nella stessa transazione

I piani di transazione vengono generati dai piani di istruzioni. Il planner impacchetta intelligentemente le istruzioni in transazioni di dimensioni ottimali, rispettando i tuoi vincoli di ordinamento. Il piano di transazione risultante può quindi essere:

  • Eseguito — firmato e inviato alla rete, con transazioni parallele inviate contemporaneamente
  • Simulato — eseguito in modalità dry-run sulla rete per verificare prima dell'invio
  • Serializzato — compilato in base64 per servizi di firma esterni o flussi di lavoro multi-party

Questo approccio a due livelli ti permette di ragionare in termini di operazioni ("trasferisci ad Alice, poi trasferisci a Bob") mentre la libreria gestisce i meccanismi di dimensionamento delle transazioni, impacchettamento ed esecuzione parallela.

Is this page helpful?

Indice

Modifica Pagina

Gestito da

© 2026 Solana Foundation.
Tutti i diritti riservati.
Rimani Connesso