Transazioni

Per interagire con la rete Solana, devi inviare una transazione. Puoi pensare a una transazione come a una busta che contiene diversi moduli. Ogni modulo è un'istruzione che dice alla rete cosa fare. Inviare la transazione è come spedire la busta affinché i moduli possano essere elaborati.

L'esempio seguente mostra una versione semplificata di due transazioni. Quando la prima transazione viene elaborata, eseguirà una singola istruzione. Quando la seconda transazione viene elaborata, eseguirà tre istruzioni in ordine sequenziale: prima l'istruzione 1, seguita dall'istruzione 2, seguita dall'istruzione 3.

Le transazioni sono atomiche: se una singola istruzione fallisce, l'intera transazione fallirà e non avverrà alcuna modifica.

Un diagramma semplificato che mostra due transazioniUn diagramma semplificato che mostra due transazioni

Una Transaction consiste nelle seguenti informazioni:

  • signatures: Un array di firme
  • message: Informazioni sulla transazione, inclusa la lista di istruzioni da elaborare
Transaction
pub struct Transaction {
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub signatures: Vec<Signature>,
#[wasm_bindgen(skip)]
pub message: Message,
}

Diagramma che mostra le due parti di una transazioneDiagramma che mostra le due parti di una transazione

Le transazioni hanno un limite di dimensione totale di 1232 byte. Questo limite include sia l'array signatures che la struttura message.

Questo limite deriva dalla dimensione dell'unità massima di trasmissione (MTU) IPv6 di 1280 byte, meno 48 byte per le intestazioni di rete (40 byte IPv6 + 8 byte di intestazione).

Diagramma che mostra il formato della transazione e i limiti di dimensioneDiagramma che mostra il formato della transazione e i limiti di dimensione

Firme

L'array signatures della transazione contiene strutture Signature. Ogni Signature è di 64 byte e viene creata firmando il Message della transazione con la chiave privata dell'account. Una firma deve essere fornita per ogni account firmatario incluso in qualsiasi istruzione della transazione.

La prima firma appartiene all'account che pagherà la commissione base della transazione ed è la firma della transazione. La firma della transazione può essere utilizzata per cercare i dettagli della transazione sulla rete.

Messaggio

Il message della transazione è una struttura Message che contiene le seguenti informazioni:

Per risparmiare spazio, la transazione non memorizza i permessi per ogni account individualmente. Invece, i permessi degli account sono determinati utilizzando il header e gli 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>,
}

Intestazione

Il header del messaggio è una struttura MessageHeader. Contiene le seguenti informazioni:

  • num_required_signatures: Il numero totale di firme richieste dalla transazione
  • num_readonly_signed_accounts: Il numero totale di account di sola lettura che richiedono firme
  • num_readonly_unsigned_accounts: Il numero totale di account di sola lettura che non richiedono firme
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,
}

Diagramma che mostra le tre parti dell'intestazione del messaggioDiagramma che mostra le tre parti dell'intestazione del messaggio

Indirizzi degli account

Gli account_keys del messaggio sono un array di indirizzi di account, inviati in formato array compatto. Il prefisso dell'array indica la sua lunghezza. Ogni elemento nell'array è una chiave pubblica, che punta a un account utilizzato dalle sue istruzioni. L'array accounts_keys deve essere completo e rigorosamente ordinato come segue:

  1. Firmatario + Scrivibile
  2. Firmatario + Sola lettura
  3. Non firmatario + Scrivibile
  4. Non firmatario + Sola lettura

L'ordinamento rigoroso consente all'array account_keys di essere combinato con le informazioni nell'header del messaggio per determinare i permessi per ciascun account.

Diagramma che mostra l'ordine dell'array degli indirizzi degli accountDiagramma che mostra l'ordine dell'array degli indirizzi degli account

Blockhash recente

Il recent_blockhash del messaggio è un valore hash che funge da timestamp della transazione e previene transazioni duplicate. Un blockhash scade dopo 150 blocchi. (Equivalente a un minuto—assumendo che ogni blocco duri 400ms.) Dopo la scadenza del blocco, la transazione è scaduta e non può essere elaborata.

Il metodo RPC getLatestBlockhash ti permette di ottenere il blockhash corrente e l'altezza dell'ultimo blocco in cui il blockhash sarà valido.

Istruzioni

Il instructions del messaggio è un array di tutte le istruzioni da elaborare, inviate in formato array compatto. Il prefisso dell'array indica la sua lunghezza. Ogni elemento nell'array è una struttura CompiledInstruction e include le seguenti informazioni:

  1. program_id_index: Un indice che punta a un indirizzo nell'array account_keys. Questo valore indica l'indirizzo del programma che elabora l'istruzione.
  2. accounts: Un array di indici che puntano agli indirizzi nell'array account_keys. Ogni indice punta all'indirizzo di un account richiesto per questa istruzione.
  3. data: Un array di byte che specifica quale istruzione invocare sul programma. Include anche qualsiasi dato aggiuntivo richiesto dall'istruzione. (Ad esempio, argomenti della funzione)
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 compatto di istruzioniArray compatto di istruzioni

Struttura di esempio della transazione

Il seguente esempio mostra la struttura di una transazione che contiene una singola istruzione di trasferimento 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.

Il codice seguente mostra l'output degli snippet di codice precedenti. Il formato differisce tra gli SDK, ma nota che ogni istruzione contiene le stesse informazioni richieste.

{
"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
}
}
]
}

Dopo che una transazione è stata inviata, puoi recuperare i suoi dettagli utilizzando la firma della transazione e il metodo RPC getTransaction. La risposta avrà una struttura simile al seguente snippet.

Puoi anche trovare la transazione utilizzando 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?

Indice

Modifica Pagina

Gestito da

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