Anweisungen sind der grundlegende Baustein für die Interaktion mit der Solana Blockchain. Eine Anweisung ist im Wesentlichen eine öffentliche Funktion, die jeder Nutzer des Solana-Netzwerks aufrufen kann. Jede Anweisung wird verwendet, um eine bestimmte Aktion auszuführen. Die Ausführungslogik für Anweisungen ist in Programmen gespeichert, wobei jedes Programm seinen eigenen Satz von Anweisungen definiert. Um mit dem Solana-Netzwerk zu interagieren, werden eine oder mehrere Anweisungen zu einer Transaktion hinzugefügt und zur Verarbeitung an das Netzwerk gesendet.
SOL-Überweisungsbeispiel
Das folgende Diagramm zeigt, wie Transaktionen und Anweisungen zusammenarbeiten, um Benutzern die Interaktion mit dem Netzwerk zu ermöglichen. In diesem Beispiel wird SOL von einem Konto auf ein anderes übertragen.
Die Metadaten des Absenderkontos geben an, dass es die Transaktion signieren muss. (Dies ermöglicht dem System Program, die lamports abzuziehen.) Sowohl das Absender- als auch das Empfängerkonto müssen beschreibbar sein, damit sich ihr Lamport-Guthaben ändern kann. Um diese Anweisung auszuführen, sendet die Wallet des Absenders die Transaktion mit ihrer Signatur und der Nachricht, die die SOL-Überweisungsanweisung enthält.
SOL-Überweisungsdiagramm
Nachdem die Transaktion gesendet wurde, verarbeitet das System Program die Überweisungsanweisung und aktualisiert das Lamport-Guthaben beider Konten.
SOL-Überweisungsprozessdiagramm
Das folgende Beispiel zeigt den Code, der für die obigen Diagramme relevant ist. (Siehe die Anweisung zur Überweisung des System Programs.)
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 clusterconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate sender and recipient keypairsconst 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 airdropawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: sender.address,lamports: lamports(LAMPORTS_PER_SOL), // 1 SOLcommitment: "confirmed"});// Check balance before transferconst { 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 recipientconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount // 0.01 SOL in lamports});// Add the transfer instruction to a new transactionconst { 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 networkconst signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });const transactionSignature = getSignatureFromTransaction(signedTransaction);// Check balance after transferconst { 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);
Anweisungen
Diagramm, das eine Transaktion mit einer Anweisung darstellt, aufgeteilt in ihre 3 Komponenten
Eine
Instruction
besteht aus den folgenden Informationen:
program_id: Die ID des aufgerufenen Programms.accounts: Ein Array von Konto-Metadatendata: Ein Byte-Array mit zusätzlichen [Daten], die von der Anweisung verwendet werden.
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
Die program_id der Anweisung ist
die öffentliche Schlüsseladresse des Programms, das die Geschäftslogik der
Anweisung enthält.
Konten-Metadaten
Das accounts-Array der Anweisung ist ein Array von
AccountMeta
Strukturen. Für jedes Konto, mit dem die Anweisung interagiert, müssen Metadaten
bereitgestellt werden. (Dies ermöglicht es Transaktionen, Anweisungen parallel
auszuführen, solange sie nicht dasselbe Konto ändern.)
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.
Die Konten-Metadaten enthalten die folgenden Informationen:
- pubkey: Die öffentliche Schlüsseladresse des Kontos
- is_signer: Auf
truegesetzt, wenn das Konto die Transaktion signieren muss - is_writable: Auf
truegesetzt, wenn die Anweisung die Daten des Kontos ändert
Um zu wissen, welche Konten eine Anweisung benötigt, einschließlich welche beschreibbar, nur lesbar sein müssen oder die Transaktion signieren müssen, müssen Sie die Implementierung der Anweisung, wie vom Programm definiert, konsultieren.
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
Die data der Anweisung ist ein Byte-Array, das angibt, welche Anweisung des
Programms aufgerufen werden soll. Es enthält auch alle von der Anweisung
benötigten Argumente.
Beispiel für die Erstellung einer Anweisung
Das folgende Beispiel zeigt die Struktur einer SOL-Überweisungsanweisung.
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));
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 man die Transfer-Anweisung manuell erstellt.
(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 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?