Anweisungen
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);
Console
Click to execute the code.
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 Konten-Metadatendata
: Ein Byte-Array mit zusätzlichen [Daten], die von der Anweisung verwendet werden.
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
Die program_id
der Anweisung ist
die pubkey-Adresse 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 die parallele Ausführung von Anweisungen
in einer Transaktion, solange sie nicht dasselbe Konto modifizieren.)
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 AccountMetaStrukturen in ihrem accountsArray.
Die Konten-Metadaten enthalten die folgenden Informationen:
- pubkey: Die öffentliche Schlüsseladresse des Kontos
- is_signer: Auf
true
gesetzt, wenn das Konto die Transaktion signieren muss - is_writable: Auf
true
gesetzt, wenn die Anweisung die Daten des Kontos modifiziert
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.
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,}
Daten
Das data
der Anweisung ist ein Byte-Array, das angibt, welche der
Programm-Anweisungen 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));
Console
Click to execute the code.
Der folgende Code zeigt die Ausgabe der vorherigen Codebeispiele. Das Format
unterscheidet sich je nach SDK, aber beachten Sie, dass jede Anweisung die
gleichen 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 Tab Expanded Instruction
ist funktional äquivalent zum Tab
Instruction
.)
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?