Ringkasan
Sebuah instruksi memiliki 3 field: program_id (program mana yang akan
dipanggil), accounts (daftar AccountMeta dengan flag is_signer/is_writable),
dan data (array byte berisi data yang diinterpretasikan oleh program).
Struktur instruksi
Sebuah
Instruction
terdiri dari tiga field:
program_id: ID dari program yang dipanggil.accounts: Array berisi metadata akundata: Array byte dengan data tambahan yang digunakan oleh instruksi.
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 instruksi adalah alamat
kunci publik dari program yang berisi logika eksekusi instruksi. Runtime
menggunakan field ini untuk mengarahkan instruksi ke program yang tepat untuk
diproses.
Metadata akun
Array accounts instruksi adalah daftar terurut dari struct
AccountMeta.
Metadata harus disediakan untuk setiap akun yang berinteraksi dengan instruksi.
Validator menggunakan metadata ini untuk menentukan transaksi mana yang dapat
berjalan secara paralel. Transaksi yang menulis ke akun berbeda dapat dieksekusi
secara paralel.
Diagram di bawah ini menggambarkan sebuah transaksi yang berisi satu instruksi.
Array accounts instruksi tersebut berisi metadata untuk dua akun.
Sebuah transaksi dengan satu instruksi. Instruksi tersebut berisi dua struct AccountMeta dalam array accounts-nya.
Setiap AccountMeta memiliki tiga field:
- pubkey: Alamat kunci publik akun
- is_signer: Diatur ke
truejika akun harus menandatangani transaksi - is_writable: Diatur ke
truejika instruksi memodifikasi data akun
Untuk mengetahui akun mana yang diperlukan oleh sebuah instruksi, termasuk yang harus dapat ditulis, hanya-baca, atau menandatangani transaksi, Anda harus merujuk pada implementasi instruksi tersebut, sebagaimana didefinisikan oleh program.
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
Field data instruksi adalah array byte yang memberi tahu program fungsi mana
yang akan dipanggil dan menyediakan argumen untuk fungsi tersebut. Data biasanya
dimulai dengan byte diskriminator atau indeks yang mengidentifikasi fungsi
target, diikuti oleh argumen yang diserialisasi. Format encoding didefinisikan
oleh setiap program (misalnya, serialisasi Borsh atau tata letak khusus).
Konvensi encoding umum:
- Program inti (System, Stake, Vote): Menggunakan indeks varian enum yang diserialisasi Bincode diikuti oleh argumen yang diserialisasi.
- Program Anchor: Menggunakan diskriminator 8-byte (8 byte pertama dari hash
SHA-256 dari
"global:<function_name>") diikuti oleh argumen yang diserialisasi Borsh.
Runtime tidak menginterpretasikan field data. Field ini diteruskan apa adanya
ke entrypoint process_instruction program.
Instruksi terkompilasi
Ketika instruksi diserialisasi ke dalam pesan transaksi, instruksi tersebut
menjadi struct
CompiledInstruction
yang menggantikan semua kunci publik dengan indeks integer kompak ke dalam array
account_keys pesan.
Contoh: instruksi transfer SOL
Contoh di bawah ini menunjukkan struktur instruksi transfer SOL.
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));
Kode di bawah ini menunjukkan output dari cuplikan kode sebelumnya. Formatnya
akan berbeda antar SDK, tetapi perhatikan bahwa setiap instruksi berisi tiga
bagian informasi yang diperlukan yang sama: 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}}
Contoh di bawah ini menunjukkan cara membuat instruksi transfer secara manual.
(Tab Expanded Instruction secara fungsional setara dengan tab Instruction.)
Dalam praktiknya, Anda biasanya tidak perlu membuat Instruction secara
manual. Sebagian besar program menyediakan library klien dengan fungsi helper
yang membuat instruksi untuk Anda. Jika library tidak tersedia, Anda dapat
membuat instruksi secara manual.
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?