Οδηγίες

Οι οδηγίες είναι το θεμελιώδες δομικό στοιχείο για την αλληλεπίδραση με το blockchain του Solana. Μια οδηγία είναι ουσιαστικά μια δημόσια συνάρτηση που οποιοσδήποτε χρησιμοποιεί το δίκτυο Solana μπορεί να καλέσει. Κάθε οδηγία χρησιμοποιείται για την εκτέλεση μιας συγκεκριμένης ενέργειας. Η λογική εκτέλεσης για τις οδηγίες αποθηκεύεται στα προγράμματα, όπου κάθε πρόγραμμα ορίζει το δικό του σύνολο οδηγιών. Για να αλληλεπιδράσετε με το δίκτυο Solana, μία ή περισσότερες οδηγίες προστίθενται σε μια συναλλαγή και αποστέλλονται στο δίκτυο για επεξεργασία.

Παράδειγμα μεταφοράς SOL

Το παρακάτω διάγραμμα δείχνει πώς οι συναλλαγές και οι οδηγίες συνεργάζονται για να επιτρέψουν στους χρήστες να αλληλεπιδράσουν με το δίκτυο. Σε αυτό το παράδειγμα, το SOL μεταφέρεται από έναν λογαριασμό σε έναν άλλο.

Τα μεταδεδομένα του λογαριασμού αποστολέα υποδεικνύουν ότι πρέπει να υπογράψει για τη συναλλαγή. (Αυτό επιτρέπει στο System Program να αφαιρέσει lamports.) Τόσο ο λογαριασμός αποστολέα όσο και ο λογαριασμός παραλήπτη πρέπει να είναι εγγράψιμοι, ώστε να μπορεί να αλλάξει το υπόλοιπο των lamport τους. Για να εκτελέσει αυτή την οδηγία, το πορτοφόλι του αποστολέα στέλνει τη συναλλαγή που περιέχει την υπογραφή του και το μήνυμα που περιέχει την οδηγία μεταφοράς SOL.

Διάγραμμα μεταφοράς SOLΔιάγραμμα μεταφοράς SOL

Μετά την αποστολή της συναλλαγής, το System Program επεξεργάζεται την οδηγία μεταφοράς και ενημερώνει το υπόλοιπο lamport και των δύο λογαριασμών.

Διάγραμμα διαδικασίας μεταφοράς SOLΔιάγραμμα διαδικασίας μεταφοράς SOL

Το παρακάτω παράδειγμα δείχνει τον κώδικα που σχετίζεται με τα παραπάνω διαγράμματα. (Δείτε την οδηγία μεταφοράς του System Program.)

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
// Create a connection to cluster
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate sender and recipient keypairs
const sender = await generateKeyPairSigner();
const recipient = await generateKeyPairSigner();
const LAMPORTS_PER_SOL = 1_000_000_000n;
const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL
// Fund sender with airdrop
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: sender.address,
lamports: lamports(LAMPORTS_PER_SOL), // 1 SOL
commitment: "confirmed"
});
// Check balance before transfer
const { value: preBalance1 } = await rpc.getBalance(sender.address).send();
const { value: preBalance2 } = await rpc.getBalance(recipient.address).send();
// Create a transfer instruction for transferring SOL from sender to recipient
const transferInstruction = getTransferSolInstruction({
source: sender,
destination: recipient.address,
amount: transferAmount // 0.01 SOL in lamports
});
// Add the transfer instruction to a new transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(sender, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions([transferInstruction], tx)
);
// Send the transaction to the network
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
const transactionSignature = getSignatureFromTransaction(signedTransaction);
// Check balance after transfer
const { value: postBalance1 } = await rpc.getBalance(sender.address).send();
const { value: postBalance2 } = await rpc.getBalance(recipient.address).send();
console.log(
"Sender prebalance:",
Number(preBalance1) / Number(LAMPORTS_PER_SOL)
);
console.log(
"Recipient prebalance:",
Number(preBalance2) / Number(LAMPORTS_PER_SOL)
);
console.log(
"Sender postbalance:",
Number(postBalance1) / Number(LAMPORTS_PER_SOL)
);
console.log(
"Recipient postbalance:",
Number(postBalance2) / Number(LAMPORTS_PER_SOL)
);
console.log("Transaction Signature:", transactionSignature);
Console
Click to execute the code.

Οδηγίες

Διάγραμμα που απεικονίζει μια συναλλαγή με μια οδηγία, χωρισμένη στα 3 συστατικά τηςΔιάγραμμα που απεικονίζει μια συναλλαγή με μια οδηγία, χωρισμένη στα 3 συστατικά της

Μια Instruction αποτελείται από τις ακόλουθες πληροφορίες:

  • program_id: Το ID του προγράμματος που καλείται.
  • accounts: Ένας πίνακας μεταδεδομένων λογαριασμού
  • data: Ένας πίνακας byte με πρόσθετα [δεδομένα] που θα χρησιμοποιηθούν από την εντολή.
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 της εντολής είναι η διεύθυνση δημόσιου κλειδιού του προγράμματος που περιέχει την επιχειρησιακή λογική της εντολής.

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

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

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

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

Τα μεταδεδομένα λογαριασμού περιλαμβάνουν τις ακόλουθες πληροφορίες:

  • 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 της εντολής είναι ένας πίνακας byte που καθορίζει ποια από τις εντολές του προγράμματος θα κληθεί. Περιλαμβάνει επίσης τυχόν ορίσματα που απαιτούνται από την εντολή.

Παράδειγμα δημιουργίας εντολής

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

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

Is this page helpful?

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

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

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

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