Δομή εντολών

Περίληψη

Μια εντολή έχει 3 πεδία: program_id (ποιο πρόγραμμα να κληθεί), accounts (λίστα AccountMeta με σημαίες is_signer/is_writable) και data (πίνακας byte δεδομένων που ερμηνεύει το πρόγραμμα).

Δομή εντολής

Μια Instruction αποτελείται από τρία πεδία:

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 της εντολής είναι η δημόσια διεύθυνση κλειδιού του προγράμματος που περιέχει τη λογική εκτέλεσης της εντολής. Το runtime χρησιμοποιεί αυτό το πεδίο για να δρομολογήσει την εντολή στο σωστό πρόγραμμα για επεξεργασία.

Μεταδεδομένα λογαριασμού

Ο πίνακας accounts της εντολής είναι μια ταξινομημένη λίστα από δομές AccountMeta. Πρέπει να παρέχονται μεταδεδομένα για κάθε λογαριασμό με τον οποίο αλληλεπιδρά η εντολή. Ο validator χρησιμοποιεί αυτά τα μεταδεδομένα για να καθορίσει ποιες συναλλαγές μπορούν να εκτελεστούν παράλληλα. Συναλλαγές που γράφουν σε διαφορετικούς λογαριασμούς μπορούν να εκτελεστούν παράλληλα.

Το παρακάτω διάγραμμα απεικονίζει μια συναλλαγή που περιέχει μία μόνο εντολή. Ο πίνακας accounts της εντολής περιέχει μεταδεδομένα για δύο λογαριασμούς.

Μια συναλλαγή με μία εντολή. Η εντολή περιέχει δύο δομές AccountMeta στον πίνακα accounts της.Μια συναλλαγή με μία εντολή. Η εντολή περιέχει δύο δομές AccountMeta στον πίνακα accounts της.

Κάθε AccountMeta έχει τρία πεδία:

  • pubkey: Η δημόσια διεύθυνση κλειδιού του λογαριασμού
  • is_signer: Ορίζεται σε true αν ο λογαριασμός πρέπει να υπογράψει τη συναλλαγή
  • is_writable: Ορίζεται σε true αν η εντολή τροποποιεί τα δεδομένα του λογαριασμού

Για να μάθετε ποιους λογαριασμούς απαιτεί μια εντολή, συμπεριλαμβανομένων ποιοι πρέπει να είναι εγγράψιμοι, μόνο για ανάγνωση ή να υπογράφουν τη συναλλαγή, πρέπει να ανατρέξετε στην υλοποίηση της εντολής, όπως ορίζεται από το πρόγραμμα.

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

Δεδομένα

Το πεδίο data της εντολής είναι ένας πίνακας bytes που υποδεικνύει στο πρόγραμμα ποια συνάρτηση να καλέσει και παρέχει τα ορίσματα για αυτή τη συνάρτηση. Τα δεδομένα τυπικά ξεκινούν με ένα discriminator ή index byte(s) που προσδιορίζει τη στοχευόμενη συνάρτηση, ακολουθούμενο από τα σειριοποιημένα ορίσματα. Η μορφή κωδικοποίησης ορίζεται από κάθε πρόγραμμα (για παράδειγμα, σειριοποίηση Borsh ή προσαρμοσμένη διάταξη).

Κοινές συμβάσεις κωδικοποίησης:

  • Βασικά προγράμματα (System, Stake, Vote): Χρησιμοποιούν ένα δείκτη παραλλαγής enum σειριοποιημένο με Bincode ακολουθούμενο από σειριοποιημένα ορίσματα.
  • Προγράμματα Anchor: Χρησιμοποιούν ένα discriminator 8-byte (τα πρώτα 8 bytes του SHA-256 hash του "global:<function_name>") ακολουθούμενο από ορίσματα σειριοποιημένα με Borsh.

Το runtime δεν ερμηνεύει το πεδίο data. Μεταβιβάζεται ως έχει στο σημείο εισόδου process_instruction του προγράμματος.

Μεταγλωττισμένη εντολή

Όταν οι εντολές σειριοποιούνται σε ένα μήνυμα συναλλαγής, μετατρέπονται σε δομές CompiledInstruction που αντικαθιστούν όλα τα δημόσια κλειδιά με συμπαγείς ακέραιους δείκτες στον πίνακα account_keys του μηνύματος.

Παράδειγμα: εντολή μεταφοράς SOL

Το παρακάτω παράδειγμα δείχνει τη δομή μιας εντολής μεταφοράς 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.

Ο παρακάτω κώδικας δείχνει το αποτέλεσμα από τα προηγούμενα αποσπάσματα κώδικα. Η μορφή θα διαφέρει μεταξύ των SDK, αλλά παρατηρήστε ότι κάθε εντολή περιέχει τα ίδια τρία απαιτούμενα στοιχεία πληροφοριών: 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
}
}

Τα παρακάτω παραδείγματα δείχνουν πώς να δημιουργήσετε χειροκίνητα την εντολή μεταφοράς. (Η καρτέλα Expanded Instruction είναι λειτουργικά ισοδύναμη με την καρτέλα Instruction.)

Στην πράξη, συνήθως δεν χρειάζεται να κατασκευάσετε ένα Instruction χειροκίνητα. Τα περισσότερα προγράμματα παρέχουν βιβλιοθήκες client με βοηθητικές συναρτήσεις που δημιουργούν τις εντολές για εσάς. Εάν δεν είναι διαθέσιμη κάποια βιβλιοθήκη, μπορείτε να δημιουργήσετε χειροκίνητα την εντολή.

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

Is this page helpful?

Πίνακας Περιεχομένων

Επεξεργασία Σελίδας

Διαχειρίζεται από

© 2026 Ίδρυμα Solana.
Με επιφύλαξη παντός δικαιώματος.
Συνδεθείτε