Pagamentos em lote

Uma transação Solana é um contêiner que contém uma ou mais instruções. Cada instrução é uma operação—transferir tokens, criar uma conta, chamar um programa. A rede executa todas as instruções em uma transação sequencialmente e atomicamente: ou todas as instruções são bem-sucedidas, ou a transação inteira falha e é revertida.

Isso significa que você pode agrupar várias transferências em uma única transação. Em vez de enviar três transações separadas para pagar três destinatários, você envia uma transação com três instruções de transferência. Isso é mais rápido (uma confirmação em vez de três) e mais barato (uma taxa base em vez de três). Aqui está um exemplo ilustrativo de como os pagamentos (referidos como "drops" nesta imagem) são agrupados em uma única transação e várias transações são enviadas para lidar com o lote maior.

Diagrama de pagamentos em loteDiagrama de pagamentos em lote

Fonte: QuickNode - How to Send Bulk Transactions on Solana

Para mais informações sobre transações e instruções, consulte os guias Transações e Instruções.

O passo a passo abaixo mostra como carregar várias instruções de transferência em uma única transação para pagamentos em lote.

Agrupando instruções em uma única transação

Uma transação Solana pode conter várias transferências para diferentes destinatários. Você assina uma vez, paga uma taxa de transação e todas as transferências são liquidadas juntas. Se qualquer transferência falhar, a transação inteira é rejeitada.

Consulte Como funcionam os pagamentos na Solana para conceitos fundamentais de pagamento.

Agrupar várias transferências requer construir cada instrução separadamente e, em seguida, combiná-las em uma única transação.

As etapas abaixo mostram o fluxo principal. Consulte a Demo para código completo executável.

Derivar contas de token

Primeiro, derive os endereços de conta de token associada (ATA) para o remetente e cada destinatário. As ATAs são endereços determinísticos baseados na carteira e no mint.

Criar instruções de transferência

Crie uma instrução de transferência separada para cada destinatário. Cada instrução especifica:

  • endereço da conta de token de origem
  • endereço da conta de token de destino
  • autoridade (endereço do proprietário da conta de token de origem)
  • quantidade em unidades base (ajustada para os decimais do mint)

Enviar como transação única

Adicione todas as instruções de transferência numa única transação. Isto executa todas as transferências atomicamente, ou todas as transferências são bem-sucedidas ou a transação inteira falha.

Verificar saldos

Após a transferência em lote, verifique os saldos de token para todas as partes usando o auxiliar splToken.

Derivar contas de token

Primeiro, derive os endereços de conta de token associada (ATA) para o remetente e cada destinatário. As ATAs são endereços determinísticos baseados na carteira e no mint.

Criar instruções de transferência

Crie uma instrução de transferência separada para cada destinatário. Cada instrução especifica:

  • endereço da conta de token de origem
  • endereço da conta de token de destino
  • autoridade (endereço do proprietário da conta de token de origem)
  • quantidade em unidades base (ajustada para os decimais do mint)

Enviar como transação única

Adicione todas as instruções de transferência numa única transação. Isto executa todas as transferências atomicamente, ou todas as transferências são bem-sucedidas ou a transação inteira falha.

Verificar saldos

Após a transferência em lote, verifique os saldos de token para todas as partes usando o auxiliar 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
});

Demonstração

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.

Escalar com planeamento de transações

Uma única transação tem limites de tamanho—aproximadamente 1232 bytes. Para operações em lote grandes (folha de pagamento para centenas de funcionários, airdrops em massa), excederá este limite e precisará dividir o trabalho em múltiplas transações.

Embora seja livre de criar a sua própria lógica de distribuição de transações, o pacote @solana/instruction-plans (parte do Solana Kit) trata disto em dois níveis:

Planos de instrução definem as suas operações e as suas restrições de ordenação:

  • Sequencial — instruções que devem ser executadas por ordem
  • Paralelo — instruções que podem ser executadas em qualquer ordem
  • Não divisível — instruções que devem permanecer juntas na mesma transação

Planos de transação são gerados a partir de planos de instrução. O planeador empacota inteligentemente as instruções em transações de tamanho ideal, respeitando as suas restrições de ordenação. O plano de transação resultante pode então ser:

  • Executado — assinado e enviado para a rede, com transações paralelas enviadas simultaneamente
  • Simulado — executado em modo de teste contra a rede para verificação antes do envio
  • Serializado — compilado para base64 para serviços de assinatura externos ou fluxos de trabalho multipartidários

Esta abordagem de dois níveis permite-lhe pensar em termos de operações ("transferir para a Alice, depois transferir para o Bob") enquanto a biblioteca trata da mecânica de dimensionamento de transações, empacotamento e execução paralela.

Is this page helpful?

Índice

Editar Página

Gerenciado por

© 2026 Fundação Solana.
Todos os direitos reservados.
Conecte-se
  • Blog