Struktura instrukcji

Podsumowanie

Instrukcja posiada 3 pola: program_id (określa, który program wywołać), accounts (lista AccountMeta z flagami is_signer/is_writable) oraz data (tablica bajtów z danymi interpretowanymi przez program).

Struktura instrukcji

Instrukcja Instruction składa się z trzech pól:

  • program_id: ID programu, który jest wywoływany.
  • accounts: Tablica metadanych kont
  • data: Tablica bajtów z dodatkowymi danymi, które zostaną użyte przez instrukcję.
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>,
}

Program ID

program_id instrukcji to adres publiczny programu, który zawiera logikę wykonania instrukcji. Środowisko uruchomieniowe wykorzystuje to pole, aby przekierować instrukcję do odpowiedniego programu do przetworzenia.

Metadane kont

Tablica accounts instrukcji to uporządkowana lista struktur AccountMeta. Metadane muszą być podane dla każdego konta, z którym instrukcja wchodzi w interakcję. Validator wykorzystuje te metadane, aby określić, które transakcje mogą być wykonywane równolegle. Transakcje zapisujące do różnych kont mogą być wykonywane jednocześnie.

Poniższy diagram przedstawia transakcję zawierającą jedną instrukcję. Tablica accounts instrukcji zawiera metadane dla dwóch kont.

Transakcja z jedną instrukcją. Instrukcja zawiera dwie struktury AccountMeta w swojej tablicy accounts.Transakcja z jedną instrukcją. Instrukcja zawiera dwie struktury AccountMeta w swojej tablicy accounts.

Każda AccountMeta posiada trzy pola:

  • pubkey: Publiczny adres konta
  • is_signer: Ustawione na true, jeśli konto musi podpisać transakcję
  • is_writable: Ustawione na true, jeśli instrukcja modyfikuje dane konta

Aby dowiedzieć się, jakie konta są wymagane przez instrukcję, w tym które muszą być zapisywalne, tylko do odczytu lub muszą podpisać transakcję, należy odwołać się do implementacji instrukcji, zgodnie z definicją programu.

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

Dane

Pole data instrukcji to tablica bajtów, która informuje program, którą funkcję wywołać i przekazuje argumenty do tej funkcji. Dane typowo zaczynają się od bajtu (lub bajtów) dyskryminatora lub indeksu, który identyfikuje docelową funkcję, a następnie znajdują się zserializowane argumenty. Format kodowania definiowany jest przez każdy program indywidualnie (na przykład serializacja Borsh lub własny układ).

Typowe konwencje kodowania:

  • Programy rdzeniowe (System, Stake, Vote): Używają wariantu enum zserializowanego przez Bincode jako indeks, po którym następują zserializowane argumenty.
  • Programy Anchor: Używają 8-bajtowego dyskryminatora (pierwsze 8 bajtów skrótu SHA-256 z "global:<function_name>"), po którym następują argumenty zserializowane przez Borsh.

Środowisko uruchomieniowe nie interpretuje pola data. Jest ono przekazywane w niezmienionej postaci do punktu wejścia programu process_instruction.

Skompilowana instrukcja

Gdy instrukcje są serializowane do wiadomości transakcji, stają się CompiledInstruction strukturami, które zastępują wszystkie klucze publiczne kompaktowymi indeksami całkowitymi w tablicy account_keys wiadomości.

Przykład: instrukcja transferu SOL

Poniższy przykład pokazuje strukturę instrukcji transferu 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.

Poniższy kod pokazuje wynik wcześniejszych fragmentów kodu. Format będzie się różnić w zależności od SDK, ale zwróć uwagę, że każda instrukcja zawiera te same trzy wymagane elementy: 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
}
}

Poniższe przykłady pokazują, jak ręcznie zbudować instrukcję transferu. (Zakładka Expanded Instruction jest funkcjonalnie równoważna zakładce Instruction.)

W praktyce zazwyczaj nie musisz ręcznie konstruować Instruction. Większość programów udostępnia biblioteki klienckie z funkcjami pomocniczymi, które tworzą instrukcje za Ciebie. Jeśli biblioteka nie jest dostępna, możesz zbudować instrukcję ręcznie.

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

Is this page helpful?

Spis treści

Edytuj stronę

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco