Instructies

Instructies zijn de fundamentele bouwsteen voor interactie met de Solana blockchain. Een instructie is in essentie een publieke functie die iedereen die het Solana netwerk gebruikt kan aanroepen. Elke instructie wordt gebruikt om een specifieke actie uit te voeren. De uitvoeringslogica voor instructies is opgeslagen in programma's, waarbij elk programma zijn eigen set instructies definieert. Om te interacteren met het Solana netwerk worden een of meer instructies toegevoegd aan een transactie en naar het netwerk gestuurd om te worden verwerkt.

SOL overdracht voorbeeld

Het onderstaande diagram laat zien hoe transacties en instructies samenwerken om gebruikers in staat te stellen met het netwerk te interacteren. In dit voorbeeld wordt SOL overgedragen van één account naar een ander.

De metadata van het verzendende account geeft aan dat het moet tekenen voor de transactie. (Dit stelt het System Program in staat om lamports af te trekken.) Zowel het verzendende als het ontvangende account moeten beschrijfbaar zijn, zodat hun lamport-saldo kan veranderen. Om deze instructie uit te voeren, stuurt de portemonnee van de verzender de transactie met zijn handtekening en het bericht dat de SOL-overdracht instructie bevat.

SOL overdracht diagramSOL overdracht diagram

Nadat de transactie is verzonden, verwerkt het System Program de overdracht instructie en werkt het lamport-saldo van beide accounts bij.

SOL overdracht proces diagramSOL overdracht proces diagram

Het onderstaande voorbeeld toont de code die relevant is voor de bovenstaande diagrammen. (Zie de System Program's transfer instructie.)

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.

Instructies

Diagram dat een transactie met een instructie weergeeft, opgedeeld in 3 componentenDiagram dat een transactie met een instructie weergeeft, opgedeeld in 3 componenten

Een Instruction bestaat uit de volgende informatie:

  • program_id: De ID van het programma dat wordt aangeroepen.
  • accounts: Een array van accountmetadata
  • data: Een byte-array met aanvullende [data] die door de instructie wordt gebruikt.
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

De program_id van de instructie is het pubkey-adres van het programma dat de bedrijfslogica van de instructie bevat.

Accountmetadata

De accounts array van de instructie is een array van AccountMeta structs. Metadata moet worden verstrekt voor elk account waarmee de instructie interactie heeft. (Dit maakt het mogelijk om transacties parallel instructies te laten uitvoeren, zolang ze niet dezelfde account wijzigen.)

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 structs in zijn accounts array.Een transactie met één instructie. De instructie bevat twee AccountMeta structs in zijn accounts array.

De accountmetadata bevat de volgende informatie:

  • pubkey: Het pubkey-adres van het account
  • is_signer: Ingesteld op true als het account de transactie moet ondertekenen
  • is_writable: Ingesteld op true als de instructie de gegevens van het account wijzigt

Om te weten welke accounts een instructie vereist, inclusief welke beschrijfbaar, alleen-lezen of de transactie moeten ondertekenen, moet je de implementatie van de instructie raadplegen, zoals gedefinieerd door het programma.

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

De data van de instructie is een byte-array die specificeert welke van de instructies van het programma moet worden aangeroepen. Het bevat ook eventuele argumenten die door de instructie worden vereist.

Voorbeeld van het maken van een instructie

Het onderstaande voorbeeld toont de structuur van een SOL-overdrachtsinstructie.

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.

De onderstaande code toont de output van de vorige codefragmenten. Het formaat zal verschillen tussen SDK's, maar merk op dat elke instructie dezelfde drie verplichte informatie-elementen 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 tonen hoe je handmatig de transfer-instructie kunt opbouwen. (De Expanded Instruction tab is functioneel gelijkwaardig aan de Instruction tab.)

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 opbouwen.

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

Is this page helpful?

Inhoudsopgave

Pagina Bewerken

Beheerd door

© 2025 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden