Struttura delle istruzioni

Riepilogo

Un'istruzione ha 3 campi: program_id (quale programma invocare), accounts (lista AccountMeta con flag is_signer/is_writable) e data (array di byte di dati che il programma interpreta).

Struttura delle istruzioni

Un' Instruction consiste di tre campi:

  • program_id: l'ID del programma che viene invocato.
  • accounts: un array di metadati dell'account
  • data: un array di byte con dati aggiuntivi da utilizzare per l'istruzione.
Instruction struct
pub struct Instruction {
/// Pubkey of the program that executes this instruction.
pub program_id: Pubkey,
/// Metadata describing accounts that should be passed to the program.
pub accounts: Vec<AccountMeta>,
/// Opaque data passed to the program for its own interpretation.
pub data: Vec<u8>,
}

ID del programma

Il program_id dell'istruzione è l'indirizzo della chiave pubblica del programma che contiene la logica di esecuzione dell'istruzione. Il runtime utilizza questo campo per instradare l'istruzione al programma corretto per l'elaborazione.

Metadati dell'account

L'array accounts dell'istruzione è una lista ordinata di struct AccountMeta. Devono essere forniti metadati per ogni account con cui l'istruzione interagisce. Il validator utilizza questi metadati per determinare quali transazioni possono essere eseguite in parallelo. Le transazioni che scrivono su account diversi possono essere eseguite in parallelo.

Il diagramma seguente mostra una transazione che contiene una singola istruzione. L'array accounts dell'istruzione contiene metadati per due account.

Una transazione con un'istruzione. L'istruzione contiene due struct AccountMeta nel suo array accounts.Una transazione con un'istruzione. L'istruzione contiene due struct AccountMeta nel suo array accounts.

Ogni struct AccountMeta ha tre campi:

  • pubkey: l'indirizzo della chiave pubblica dell'account
  • is_signer: impostato su true se l'account deve firmare la transazione
  • is_writable: impostato su true se l'istruzione modifica i dati dell'account

Per sapere quali account richiede un'istruzione, inclusi quali devono essere scrivibili, di sola lettura o firmare la transazione, devi fare riferimento all'implementazione dell'istruzione, come definita dal programma.

AccountMeta
pub struct AccountMeta {
/// An account's public key.
pub pubkey: Pubkey,
/// True if an `Instruction` requires a `Transaction` signature matching `pubkey`.
pub is_signer: bool,
/// True if the account data or metadata may be mutated during program execution.
pub is_writable: bool,
}

Dati

Il campo data dell'istruzione è un array di byte che indica al programma quale funzione invocare e fornisce gli argomenti per quella funzione. I dati tipicamente iniziano con un discriminatore o byte di indice che identifica la funzione target, seguito dagli argomenti serializzati. Il formato di codifica è definito da ciascun programma (ad esempio, serializzazione Borsh o un layout personalizzato).

Convenzioni di codifica comuni:

  • Programmi core (System, Stake, Vote): utilizzano un indice di variante enum serializzato con Bincode seguito da argomenti serializzati.
  • Programmi Anchor: utilizzano un discriminatore a 8 byte (i primi 8 byte dell'hash SHA-256 di "global:<function_name>") seguito da argomenti serializzati con Borsh.

Il runtime non interpreta il campo data. Viene passato così com'è all'entrypoint process_instruction del programma.

Istruzione compilata

Quando le istruzioni vengono serializzate in un messaggio di transazione, diventano struct CompiledInstruction che sostituiscono tutte le chiavi pubbliche con indici interi compatti nell'array account_keys del messaggio.

Esempio: istruzione di trasferimento SOL

L'esempio seguente mostra la struttura di un'istruzione di trasferimento SOL.

import { generateKeyPairSigner, lamports } from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
// 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
});
console.log(JSON.stringify(transferInstruction, null, 2));
Console
Click to execute the code.

Il codice seguente mostra l'output degli snippet di codice precedenti. Il formato sarà diverso tra gli SDK, ma nota che ogni istruzione contiene le stesse tre informazioni richieste: program_id, accounts, data.

{
"accounts": [
{
"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC",
"role": 3,
"signer": {
"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC",
"keyPair": {
"privateKey": {},
"publicKey": {}
}
}
},
{
"address": "2mBY6CTgeyJNJDzo6d2Umipw2aGUquUA7hLdFttNEj7p",
"role": 1
}
],
"programAddress": "11111111111111111111111111111111",
"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
}
}

Gli esempi seguenti mostrano come costruire manualmente l'istruzione di trasferimento. (La scheda Expanded Instruction è funzionalmente equivalente alla scheda Instruction.)

In pratica, di solito non è necessario costruire un'Instruction manualmente. La maggior parte dei programmi fornisce librerie client con funzioni helper che creano le istruzioni per te. Se una libreria non è disponibile, puoi costruire manualmente l'istruzione.

const transferAmount = 0.01; // 0.01 SOL
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount * LAMPORTS_PER_SOL
});

Is this page helpful?

Indice dei contenuti

Modifica pagina

Gestito da

© 2026 Solana Foundation.
Tutti i diritti riservati.
Resta connesso