Instrukcje

Instrukcje są podstawowym elementem interakcji z blockchainem Solana. Instrukcja to w zasadzie publiczna funkcja, którą może wywołać każdy użytkownik sieci Solana. Każda instrukcja służy do wykonania określonej akcji. Logika wykonania instrukcji jest przechowywana w programach, gdzie każdy program definiuje swój własny zestaw instrukcji. Aby wejść w interakcję z siecią Solana, jedna lub więcej instrukcji jest dodawana do transakcji i wysyłana do sieci w celu przetworzenia.

Przykład transferu SOL

Poniższy diagram pokazuje, jak transakcje i instrukcje współpracują, aby umożliwić użytkownikom interakcję z siecią. W tym przykładzie SOL jest przesyłany z jednego konta na drugie.

Metadane konta nadawcy wskazują, że musi ono podpisać transakcję. (Pozwala to Programowi Systemowemu odjąć lamporty.) Zarówno konto nadawcy, jak i odbiorcy muszą być zapisywalne, aby ich saldo lamportów mogło się zmienić. Aby wykonać tę instrukcję, portfel nadawcy wysyła transakcję zawierającą jego podpis oraz wiadomość zawierającą instrukcję transferu SOL.

Diagram transferu SOLDiagram transferu SOL

Po wysłaniu transakcji Program Systemowy przetwarza instrukcję transferu i aktualizuje saldo lamportów obu kont.

Diagram procesu transferu SOLDiagram procesu transferu SOL

Poniższy przykład pokazuje kod związany z powyższymi diagramami. (Zobacz instrukcję transferu Programu Systemowego tutaj.)

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.

Instrukcje

Diagram przedstawiający transakcję z instrukcją, podzieloną na 3 komponentyDiagram przedstawiający transakcję z instrukcją, podzieloną na 3 komponenty

Instrukcja Instruction składa się z następujących informacji:

  • program_id: ID programu, który jest wywoływany.
  • accounts: Tablica metadanych konta
  • data: Tablica bajtów zawierająca dodatkowe [dane], które są używane przez instrukcję.
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>,
}

ID programu

program_id instrukcji to adres klucza publicznego programu, który zawiera logikę biznesową instrukcji.

Metadane konta

Tablica accounts instrukcji to tablica struktur AccountMeta. Metadane muszą być dostarczone dla każdego konta, z którym instrukcja wchodzi w interakcję. (Pozwala to na wykonywanie instrukcji w ramach transakcji równolegle, o ile nie modyfikują tego samego konta.)

Poniższy diagram przedstawia transakcję zawierającą jedną instrukcję. Tablica accounts instrukcji zawiera metadane dla dwóch kont.

Transakcja z jedną instrukcją. Instrukcja zawiera dwie struktury AccountMeta w swojej tablicy accounts.Transakcja z jedną instrukcją. Instrukcja zawiera dwie struktury AccountMeta w swojej tablicy accounts.

Metadane konta zawierają następujące informacje:

  • pubkey: Adres klucza publicznego konta
  • is_signer: Ustawione na true, jeśli konto musi podpisać transakcję
  • is_writable: Ustawione na true, jeśli instrukcja modyfikuje dane konta

Aby dowiedzieć się, które konta są wymagane przez instrukcję, w tym które muszą być zapisywalne, tylko do odczytu lub podpisać transakcję, należy odnieść się do implementacji instrukcji, zdefiniowanej przez program.

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

Dane

data instrukcji to tablica bajtów, która określa, którą instrukcję programu należy wywołać. Zawiera również wszelkie argumenty wymagane przez instrukcję.

Przykład tworzenia instrukcji

Poniższy przykład pokazuje strukturę instrukcji transferu 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.

Kod poniżej pokazuje wynik z poprzednich fragmentów kodu. Format będzie się różnił w zależności od SDK, ale zauważ, że każda instrukcja zawiera te same trzy wymagane elementy: 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
}
}

Poniższe przykłady pokazują, jak ręcznie zbudować instrukcję transferu. (Zakładka Expanded Instruction jest funkcjonalnie równoważna zakładce Instruction.)

W praktyce zazwyczaj nie musisz ręcznie tworzyć Instruction. Większość programów dostarcza biblioteki klienckie z funkcjami pomocniczymi, które tworzą instrukcje za Ciebie. Jeśli biblioteka nie jest dostępna, możesz ręcznie zbudować instrukcję.

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

Is this page helpful?

Spis treści

Edytuj stronę

Zarządzane przez

© 2025 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco