Transações

Para interagir com a rede Solana, você deve enviar uma transação. Você pode pensar em uma transação como um envelope que contém vários formulários. Cada formulário é uma instrução que diz à rede o que fazer. Enviar a transação é como enviar o envelope pelo correio para que os formulários possam ser processados.

O exemplo abaixo mostra uma versão simplificada de duas transações. Quando a primeira transação é processada, ela executará uma única instrução. Quando a segunda transação é processada, ela executará três instruções em ordem sequencial: primeiro a instrução 1, seguida pela instrução 2, seguida pela instrução 3.

As transações são atômicas: Se uma única instrução falhar, toda a transação falhará e nenhuma alteração ocorrerá.

Um diagrama simplificado mostrando duas transaçõesUm diagrama simplificado mostrando duas transações

Uma Transaction consiste nas seguintes informações:

  • signatures: Um array de assinaturas
  • message: Informações da transação, incluindo a lista de instruções a serem processadas
Transaction
pub struct Transaction {
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub signatures: Vec<Signature>,
#[wasm_bindgen(skip)]
pub message: Message,
}

Diagrama mostrando as duas partes de uma transaçãoDiagrama mostrando as duas partes de uma transação

As transações têm um limite total de tamanho de 1232 bytes. Este limite inclui tanto o array signatures quanto a estrutura message.

Este limite vem do tamanho da Unidade Máxima de Transmissão (MTU) do IPv6 de 1280 bytes, menos 48 bytes para cabeçalhos de rede (40 bytes IPv6 + 8 bytes de cabeçalho).

Diagrama mostrando o formato da transação e limites de tamanhoDiagrama mostrando o formato da transação e limites de tamanho

Assinaturas

O array signatures da transação contém estruturas Signature. Cada Signature tem 64 bytes e é criada assinando o Message da transação com a chave privada da conta. Uma assinatura deve ser fornecida para cada conta signatária incluída em qualquer uma das instruções da transação.

A primeira assinatura pertence à conta que pagará a taxa base da transação e é a assinatura da transação. A assinatura da transação pode ser usada para consultar os detalhes da transação na rede.

Mensagem

A message da transação é uma estrutura Message que contém as seguintes informações:

Para economizar espaço, a transação não armazena permissões para cada conta individualmente. Em vez disso, as permissões das contas são determinadas usando o header e o account_keys.

Message
pub struct Message {
/// The message header, identifying signed and read-only `account_keys`.
pub header: MessageHeader,
/// All the account keys used by this transaction.
#[serde(with = "short_vec")]
pub account_keys: Vec<Pubkey>,
/// The id of a recent ledger entry.
pub recent_blockhash: Hash,
/// Programs that will be executed in sequence and committed in
/// one atomic transaction if all succeed.
#[serde(with = "short_vec")]
pub instructions: Vec<CompiledInstruction>,
}

Cabeçalho

O header da mensagem é uma estrutura MessageHeader. Ele contém as seguintes informações:

  • num_required_signatures: O número total de assinaturas exigidas pela transação
  • num_readonly_signed_accounts: O número total de contas somente leitura que exigem assinaturas
  • num_readonly_unsigned_accounts: O número total de contas somente leitura que não exigem assinaturas
MessageHeader
pub struct MessageHeader {
/// The number of signatures required for this message to be considered
/// valid. The signers of those signatures must match the first
/// `num_required_signatures` of [`Message::account_keys`].
pub num_required_signatures: u8,
/// The last `num_readonly_signed_accounts` of the signed keys are read-only
/// accounts.
pub num_readonly_signed_accounts: u8,
/// The last `num_readonly_unsigned_accounts` of the unsigned keys are
/// read-only accounts.
pub num_readonly_unsigned_accounts: u8,
}

Diagrama mostrando as três partes do cabeçalho da mensagemDiagrama mostrando as três partes do cabeçalho da mensagem

Endereços de contas

O account_keys da mensagem é um array de endereços de contas, enviado no formato de array compacto. O prefixo do array indica seu comprimento. Cada item no array é uma chave pública, apontando para uma conta usada por suas instruções. O array accounts_keys deve ser completo e estritamente ordenado da seguinte forma:

  1. Assinante + Gravável
  2. Assinante + Somente leitura
  3. Não assinante + Gravável
  4. Não assinante + Somente leitura

A ordenação estrita permite que o array account_keys seja combinado com as informações no header da mensagem para determinar as permissões para cada conta.

Diagrama mostrando a ordem do array de endereços de contasDiagrama mostrando a ordem do array de endereços de contas

Blockhash recente

O recent_blockhash da mensagem é um valor hash que atua como um timestamp da transação e impede transações duplicadas. Um blockhash expira após 150 blocos. (Equivalente a um minuto—assumindo que cada bloco leva 400ms.) Após a expiração do bloco, a transação expira e não pode ser processada.

O método RPC getLatestBlockhash permite obter o blockhash atual e a altura do último bloco no qual o blockhash será válido.

Instruções

O instructions da mensagem é um array de todas as instruções a serem processadas, enviadas no formato de array compacto. O prefixo do array indica seu comprimento. Cada item no array é uma estrutura CompiledInstruction e inclui as seguintes informações:

  1. program_id_index: Um índice que aponta para um endereço no array account_keys. Este valor indica o endereço do programa que processa a instrução.
  2. accounts: Um array de índices que apontam para endereços no array account_keys. Cada índice aponta para o endereço de uma conta necessária para esta instrução.
  3. data: Um array de bytes especificando qual instrução invocar no programa. Também inclui quaisquer dados adicionais exigidos pela instrução. (Por exemplo, argumentos de função)
CompiledInstruction
pub struct CompiledInstruction {
/// Index into the transaction keys array indicating the program account that executes this instruction.
pub program_id_index: u8,
/// Ordered indices into the transaction keys array indicating which accounts to pass to the program.
#[serde(with = "short_vec")]
pub accounts: Vec<u8>,
/// The program input data.
#[serde(with = "short_vec")]
pub data: Vec<u8>,
}

Array compacto de InstruçõesArray compacto de Instruções

Exemplo de estrutura de transação

O exemplo a seguir mostra a estrutura de uma transação que contém uma única instrução de transferência de SOL.

import {
createSolanaRpc,
generateKeyPairSigner,
lamports,
createTransactionMessage,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstructions,
pipe,
signTransactionMessageWithSigners,
getCompiledTransactionMessageDecoder
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
const rpc = createSolanaRpc("http://localhost:8899");
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// Generate sender and recipient keypairs
const sender = await generateKeyPairSigner();
const recipient = await generateKeyPairSigner();
// Define the amount to transfer
const LAMPORTS_PER_SOL = 1_000_000_000n;
const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL
// Create a transfer instruction for transferring SOL from sender to recipient
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount
});
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(sender, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions([transferInstruction], tx)
);
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Decode the messageBytes
const compiledTransactionMessage =
getCompiledTransactionMessageDecoder().decode(signedTransaction.messageBytes);
console.log(JSON.stringify(compiledTransactionMessage, null, 2));
Console
Click to execute the code.

O código abaixo mostra a saída dos snippets de código anteriores. O formato difere entre SDKs, mas observe que cada instrução contém as mesmas informações necessárias.

{
"version": 0,
"header": {
"numSignerAccounts": 1,
"numReadonlySignerAccounts": 0,
"numReadonlyNonSignerAccounts": 1
},
"staticAccounts": [
"HoCy8p5xxDDYTYWEbQZasEjVNM5rxvidx8AfyqA4ywBa",
"5T388jBjovy7d8mQ3emHxMDTbUF8b7nWvAnSiP3EAdFL",
"11111111111111111111111111111111"
],
"lifetimeToken": "EGCWPUEXhqHJWYBfDirq3mHZb4qDpATmYqBZMBy9TBC1",
"instructions": [
{
"programAddressIndex": 2,
"accountIndices": [0, 1],
"data": {
"0": 2,
"1": 0,
"2": 0,
"3": 0,
"4": 128,
"5": 150,
"6": 152,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0
}
}
]
}

Depois que uma transação é enviada, você pode recuperar seus detalhes usando a assinatura da transação e o método RPC getTransaction. A resposta terá uma estrutura semelhante ao trecho a seguir.

Você também pode encontrar a transação usando o Solana Explorer.

Transaction Data
{
"blockTime": 1745196488,
"meta": {
"computeUnitsConsumed": 150,
"err": null,
"fee": 5000,
"innerInstructions": [],
"loadedAddresses": {
"readonly": [],
"writable": []
},
"logMessages": [
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
],
"postBalances": [989995000, 10000000, 1],
"postTokenBalances": [],
"preBalances": [1000000000, 0, 1],
"preTokenBalances": [],
"rewards": [],
"status": {
"Ok": null
}
},
"slot": 13049,
"transaction": {
"message": {
"header": {
"numReadonlySignedAccounts": 0,
"numReadonlyUnsignedAccounts": 1,
"numRequiredSignatures": 1
},
"accountKeys": [
"8PLdpLxkuv9Nt8w3XcGXvNa663LXDjSrSNon4EK7QSjQ",
"7GLg7bqgLBv1HVWXKgWAm6YoPf1LoWnyWGABbgk487Ma",
"11111111111111111111111111111111"
],
"recentBlockhash": "7ZCxc2SDhzV2bYgEQqdxTpweYJkpwshVSDtXuY7uPtjf",
"instructions": [
{
"accounts": [0, 1],
"data": "3Bxs4NN8M2Yn4TLb",
"programIdIndex": 2,
"stackHeight": null
}
],
"indexToProgramIds": {}
},
"signatures": [
"3jUKrQp1UGq5ih6FTDUUt2kkqUfoG2o4kY5T1DoVHK2tXXDLdxJSXzuJGY4JPoRivgbi45U2bc7LZfMa6C4R3szX"
]
},
"version": "legacy"
}

Is this page helpful?

Índice

Editar Página

Gerenciado por

© 2025 Fundação Solana.
Todos os direitos reservados.