Anweisungsstruktur

Zusammenfassung

Eine Anweisung hat 3 Felder: program_id (welches Programm aufgerufen werden soll), accounts (AccountMeta-Liste mit is_signer/is_writable-Flags) und data (Byte-Array mit Daten, die das Programm interpretiert).

Anweisungsstruktur

Eine Instruction besteht aus drei Feldern:

  • program_id: Die ID des aufgerufenen Programms.
  • accounts: Ein Array von Konto-Metadaten
  • data: Ein Byte-Array mit zusätzlichen Daten für die Anweisung.
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>,
}

Programm-ID

Die program_id der Anweisung ist die öffentliche Schlüsseladresse des Programms, das die Ausführungslogik der Anweisung enthält. Die Runtime verwendet dieses Feld, um die Anweisung zur Verarbeitung an das richtige Programm weiterzuleiten.

Konto-Metadaten

Das accounts-Array der Anweisung ist eine geordnete Liste von AccountMeta-Strukturen. Für jedes Konto, mit dem die Anweisung interagiert, müssen Metadaten bereitgestellt werden. Der Validator verwendet diese Metadaten, um zu bestimmen, welche Transaktionen parallel ausgeführt werden können. Transaktionen, die in verschiedene Konten schreiben, können parallel ausgeführt werden.

Das folgende Diagramm zeigt eine Transaktion, die eine einzelne Anweisung enthält. Das accounts-Array der Anweisung enthält Metadaten für zwei Konten.

Eine Transaktion mit einer Anweisung. Die Anweisung enthält zwei AccountMeta-Strukturen in ihrem accounts-Array.Eine Transaktion mit einer Anweisung. Die Anweisung enthält zwei AccountMeta-Strukturen in ihrem accounts-Array.

Jede AccountMeta-Struktur hat drei Felder:

  • pubkey: Die öffentliche Schlüsseladresse des Kontos
  • is_signer: Auf true gesetzt, wenn das Konto die Transaktion signieren muss
  • is_writable: Auf true gesetzt, wenn die Anweisung die Daten des Kontos ändert

Um zu wissen, welche Konten eine Anweisung benötigt, einschließlich welche beschreibbar, schreibgeschützt sein müssen oder die Transaktion signieren müssen, müssen Sie die Implementierung der Anweisung konsultieren, wie sie vom Programm definiert ist.

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,
}

Daten

Das data-Feld der Anweisung ist ein Byte-Array, das dem Programm mitteilt, welche Funktion aufgerufen werden soll, und die Argumente für diese Funktion bereitstellt. Die Daten beginnen typischerweise mit einem Diskriminator oder Index-Byte(s), der die Zielfunktion identifiziert, gefolgt von den serialisierten Argumenten. Das Kodierungsformat wird von jedem Programm definiert (zum Beispiel Borsh-Serialisierung oder ein benutzerdefiniertes Layout).

Gängige Kodierungskonventionen:

  • Kernprogramme (System, Stake, Vote): Verwenden einen Bincode-serialisierten Enum-Variantenindex, gefolgt von serialisierten Argumenten.
  • Anchor-Programme: Verwenden einen 8-Byte-Diskriminator (die ersten 8 Bytes des SHA-256-Hashs von "global:<function_name>"), gefolgt von Borsh-serialisierten Argumenten.

Die Runtime interpretiert das data-Feld nicht. Es wird unverändert an den process_instruction-Einstiegspunkt des Programms übergeben.

Kompilierte Anweisung

Wenn Anweisungen in eine Transaktionsnachricht serialisiert werden, werden sie zu CompiledInstruction-Strukturen, die alle öffentlichen Schlüssel durch kompakte ganzzahlige Indizes in das account_keys-Array der Nachricht ersetzen.

Beispiel: SOL-Transfer-Anweisung

Das folgende Beispiel zeigt die Struktur einer SOL-Transfer-Anweisung.

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.

Der folgende Code zeigt die Ausgabe der vorherigen Code-Snippets. Das Format unterscheidet sich zwischen den SDKs, aber beachten Sie, dass jede Anweisung dieselben drei erforderlichen Informationen enthält: 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
}
}

Die folgenden Beispiele zeigen, wie die Transfer-Anweisung manuell erstellt wird. (Der Expanded Instruction-Tab ist funktional äquivalent zum Instruction-Tab.)

In der Praxis müssen Sie normalerweise keine Instruction manuell erstellen. Die meisten Programme bieten Client-Bibliotheken mit Hilfsfunktionen, die die Anweisungen für Sie erstellen. Wenn keine Bibliothek verfügbar ist, können Sie die Anweisung manuell erstellen.

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

Is this page helpful?

Inhaltsverzeichnis

Seite bearbeiten

Verwaltet von

© 2026 Solana Foundation.
Alle Rechte vorbehalten.
Verbinden Sie sich