Samenvatting
Een instructie heeft 3 velden: program_id (welk programma aan te roepen),
accounts (AccountMeta lijst met is_signer/is_writable vlaggen), en data
(byte array met data die het programma interpreteert).
Instructiestructuur
Een
Instruction
bestaat uit drie velden:
program_id: De ID van het programma dat wordt aangeroepen.accounts: Een array van account metadatadata: Een byte array met aanvullende data voor gebruik door de instructie.
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
De program_id van de instructie is
het public key adres van het programma dat de uitvoeringslogica van de
instructie bevat. De runtime gebruikt dit veld om de instructie naar het juiste
programma te routeren voor verwerking.
Account metadata
De accounts array van de instructie is een geordende lijst van
AccountMeta
structuren. Metadata moet worden verstrekt voor elk account waarmee de
instructie interacteert. De validator gebruikt deze metadata om te bepalen welke
transacties parallel kunnen worden uitgevoerd. Transacties die naar
verschillende accounts schrijven kunnen parallel worden uitgevoerd.
Het onderstaande diagram toont een transactie die één instructie bevat. De
accounts array van de instructie bevat metadata voor twee accounts.
Een transactie met één instructie. De instructie bevat twee AccountMeta structuren in zijn accounts array.
Elke AccountMeta heeft drie velden:
- pubkey: Het public key adres van het account
- is_signer: Ingesteld op
trueals het account de transactie moet ondertekenen - is_writable: Ingesteld op
trueals de instructie de data van het account wijzigt
Om te weten welke accounts een instructie vereist, inclusief welke schrijfbaar, alleen-lezen of ondertekend moeten zijn, moet je de implementatie van de instructie raadplegen zoals gedefinieerd door het programma.
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,}
Data
Het data-veld van de instructie is een byte-array die het programma vertelt
welke functie moet worden aangeroepen en de argumenten voor die functie levert.
De data begint doorgaans met een discriminator of index byte(s) die de
doelfunctie identificeert, gevolgd door de geserialiseerde argumenten. Het
coderingsformaat wordt door elk programma gedefinieerd (bijvoorbeeld
Borsh-serialisatie of een aangepaste indeling).
Veelvoorkomende coderingsconventies:
- Kernprogramma's (System, Stake, Vote): gebruiken een Bincode-geserialiseerde enum-variantindex gevolgd door geserialiseerde argumenten.
- Anchor-programma's: gebruiken een 8-byte discriminator (de eerste 8 bytes
van de SHA-256 hash van
"global:<function_name>") gevolgd door Borsh-geserialiseerde argumenten.
De runtime interpreteert het data-veld niet. Het wordt ongewijzigd doorgegeven
aan het process_instruction-toegangspunt van het programma.
Gecompileerde instructie
Wanneer instructies worden geserialiseerd in een transactiebericht, worden ze
CompiledInstruction-structs
die alle publieke sleutels vervangen door compacte integer-indices in de
account_keys-array van het bericht.
Voorbeeld: SOL-overdracht instructie
Het onderstaande voorbeeld toont de structuur van een SOL-overdracht instructie.
import { generateKeyPairSigner, lamports } from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";// Generate sender and recipient keypairsconst sender = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();// Define the amount to transferconst 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 recipientconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount});console.log(JSON.stringify(transferInstruction, null, 2));
De onderstaande code toont de output van de vorige codefragmenten. Het formaat
verschilt per SDK, maar merk op dat elke instructie dezelfde drie vereiste
informatiestukken bevat: 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}}
De onderstaande voorbeelden laten zien hoe je de transfer-instructie handmatig
kunt bouwen. (Het Expanded Instruction tabblad is functioneel equivalent aan
het Instruction tabblad.)
In de praktijk hoef je meestal geen Instruction handmatig te
construeren. De meeste programma's bieden clientbibliotheken met hulpfuncties
die de instructies voor je aanmaken. Als er geen bibliotheek beschikbaar is,
kun je de instructie handmatig bouwen.
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?