Instruksi
Instruksi adalah blok bangunan fundamental untuk berinteraksi dengan blockchain Solana. Instruksi pada dasarnya adalah fungsi publik yang dapat dipanggil oleh siapa saja yang menggunakan jaringan Solana. Setiap instruksi digunakan untuk melakukan tindakan tertentu. Logika eksekusi untuk instruksi disimpan pada program, di mana setiap program mendefinisikan serangkaian instruksinya sendiri. Untuk berinteraksi dengan jaringan Solana, satu atau lebih instruksi ditambahkan ke transaksi dan dikirim ke jaringan untuk diproses.
Contoh transfer SOL
Diagram di bawah ini menunjukkan bagaimana transaksi dan instruksi bekerja bersama untuk memungkinkan pengguna berinteraksi dengan jaringan. Dalam contoh ini, SOL ditransfer dari satu akun ke akun lainnya.
Metadata akun pengirim menunjukkan bahwa akun tersebut harus menandatangani transaksi. (Ini memungkinkan System Program untuk mengurangi lamport.) Baik akun pengirim maupun penerima harus dapat ditulis, agar saldo lamport mereka dapat berubah. Untuk mengeksekusi instruksi ini, dompet pengirim mengirimkan transaksi yang berisi tanda tangan dan pesan yang berisi instruksi transfer SOL.
Diagram transfer SOL
Setelah transaksi dikirim, System Program memproses instruksi transfer dan memperbarui saldo lamport kedua akun.
Diagram proses transfer SOL
Contoh di bawah ini menunjukkan kode yang relevan dengan diagram di atas. (Lihat instruksi transfer 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 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.
Instruksi
Diagram yang menggambarkan transaksi dengan instruksi, dibagi menjadi 3 komponen
Sebuah
Instruction
terdiri dari informasi berikut:
program_id
: ID dari program yang dipanggil.accounts
: Array dari metadata akundata
: Array byte dengan [data] tambahan yang akan digunakan oleh instruksi.
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
dari instruksi adalah
alamat pubkey dari program yang berisi logika bisnis instruksi.
Metadata akun
Array accounts
dari instruksi adalah array dari struktur
AccountMeta
.
Metadata harus disediakan untuk setiap akun yang berinteraksi dengan instruksi.
(Hal ini memungkinkan transaksi untuk mengeksekusi instruksi secara paralel,
selama tidak memodifikasi akun yang sama.)
Diagram di bawah ini menggambarkan transaksi yang berisi satu instruksi. Array
accounts
dari instruksi berisi metadata untuk dua akun.
Transaksi dengan satu instruksi. Instruksi tersebut berisi dua struktur AccountMeta dalam array accounts.
Metadata akun mencakup informasi berikut:
- pubkey: Alamat pubkey dari akun
- is_signer: Diatur ke
true
jika akun harus menandatangani transaksi - is_writable: Diatur ke
true
jika instruksi memodifikasi data akun
Untuk mengetahui akun mana yang diperlukan oleh instruksi, termasuk yang harus dapat ditulis, hanya-baca, atau menandatangani transaksi, Anda harus merujuk pada implementasi instruksi, sebagaimana didefinisikan oleh 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,}
Data
data
dari instruksi adalah array byte yang menentukan instruksi mana dari
program yang akan dipanggil. Ini juga mencakup argumen apa pun yang diperlukan
oleh instruksi.
Contoh pembuatan instruksi
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));
Console
Click to execute the code.
Kode di bawah ini menunjukkan output dari cuplikan kode sebelumnya. Format akan
berbeda antar SDK, tetapi perhatikan bahwa setiap instruksi berisi tiga bagian
informasi yang sama yang diperlukan: 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 membangun instruksi transfer secara manual.
(Tab Expanded Instruction
secara fungsional setara dengan tab Instruction
)
Dalam praktiknya, biasanya Anda tidak perlu membuat Instruction
secara
manual. Sebagian besar program menyediakan pustaka klien dengan fungsi
pembantu yang membuat instruksi untuk Anda. Jika pustaka tidak tersedia, Anda
dapat membangun 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?