Hướng dẫn

Các lệnh là khối xây dựng cơ bản để tương tác với blockchain Solana. Một lệnh về cơ bản là một hàm công khai mà bất kỳ ai sử dụng mạng Solana đều có thể gọi. Mỗi lệnh được sử dụng để thực hiện một hành động cụ thể. Logic thực thi cho các lệnh được lưu trữ trên chương trình, trong đó mỗi chương trình định nghĩa tập hợp các lệnh riêng của nó. Để tương tác với mạng Solana, một hoặc nhiều lệnh được thêm vào một giao dịch và gửi đến mạng để được xử lý.

Ví dụ chuyển SOL

Sơ đồ dưới đây cho thấy cách các giao dịch và lệnh hoạt động cùng nhau để cho phép người dùng tương tác với mạng. Trong ví dụ này, SOL được chuyển từ tài khoản này sang tài khoản khác.

Metadata của tài khoản người gửi chỉ ra rằng nó phải ký cho giao dịch. (Điều này cho phép System Program khấu trừ lamport.) Cả tài khoản người gửi và người nhận đều phải có khả năng ghi, để số dư lamport của họ có thể thay đổi. Để thực thi lệnh này, ví của người gửi gửi giao dịch chứa chữ ký của nó và thông điệp chứa lệnh chuyển SOL.

Sơ đồ chuyển SOLSơ đồ chuyển SOL

Sau khi giao dịch được gửi, System Program xử lý lệnh chuyển và cập nhật số dư lamport của cả hai tài khoản.

Sơ đồ quy trình chuyển SOLSơ đồ quy trình chuyển SOL

Ví dụ dưới đây hiển thị mã liên quan đến các sơ đồ trên. (Xem lệnh chuyển của 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.

Lệnh

Sơ đồ mô tả một giao dịch với một lệnh, được chia thành 3 thành phầnSơ đồ mô tả một giao dịch với một lệnh, được chia thành 3 thành phần

Một Instruction bao gồm các thông tin sau:

  • program_id: ID của chương trình được gọi.
  • accounts: Một mảng metadata tài khoản
  • data: Một mảng byte với [dữ liệu] bổ sung để được sử dụng bởi lệnh.
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 của lệnh là địa chỉ khóa công khai của chương trình chứa logic nghiệp vụ của lệnh.

Metadata tài khoản

Mảng accounts của lệnh là một mảng các cấu trúc AccountMeta. Metadata phải được cung cấp cho mỗi tài khoản mà lệnh tương tác với. (Điều này cho phép giao dịch thực thi các lệnh song song, miễn là chúng không sửa đổi cùng một tài khoản.)

Sơ đồ dưới đây mô tả một giao dịch chứa một lệnh duy nhất. Mảng accounts của lệnh chứa metadata cho hai tài khoản.

Một giao dịch với một lệnh. Lệnh chứa hai cấu trúc AccountMeta trong mảng accounts của nó.Một giao dịch với một lệnh. Lệnh chứa hai cấu trúc AccountMeta trong mảng accounts của nó.

Metadata tài khoản bao gồm các thông tin sau:

  • pubkey: Địa chỉ khóa công khai của tài khoản
  • is_signer: Đặt thành true nếu tài khoản phải ký giao dịch
  • is_writable: Đặt thành true nếu lệnh sửa đổi dữ liệu của tài khoản

Để biết lệnh yêu cầu những tài khoản nào, bao gồm tài khoản nào phải có thể ghi, chỉ đọc, hoặc ký giao dịch, bạn phải tham khảo triển khai của lệnh, như được định nghĩa bởi chương trình.

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

Dữ liệu

data của lệnh là một mảng byte xác định lệnh nào của chương trình sẽ được gọi. Nó cũng bao gồm bất kỳ đối số nào được yêu cầu bởi lệnh.

Ví dụ tạo lệnh

Ví dụ dưới đây cho thấy cấu trúc của một lệnh chuyển 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.

Đoạn mã dưới đây hiển thị kết quả từ các đoạn mã trước đó. Định dạng có thể khác nhau giữa các SDK, nhưng lưu ý rằng mỗi chỉ dẫn đều chứa ba thông tin bắt buộc giống nhau: 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
}
}

Các ví dụ dưới đây cho thấy cách xây dựng thủ công chỉ dẫn chuyển tiền. (Tab Expanded Instruction về mặt chức năng tương đương với tab Instruction)

Trong thực tế, bạn thường không phải tự xây dựng một Instruction thủ công. Hầu hết các chương trình đều cung cấp thư viện khách với các hàm trợ giúp tạo chỉ dẫn cho bạn. Nếu không có sẵn thư viện, bạn có thể tự xây dựng chỉ dẫn thủ công.

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

Is this page helpful?

Mục lục

Chỉnh sửa trang

Quản lý bởi

© 2025 Solana Foundation.
Đã đăng ký bản quyền.
Kết nối