Transaksi
Untuk berinteraksi dengan jaringan Solana, Anda harus mengirim transaksi. Anda dapat menganggap transaksi sebagai amplop yang berisi beberapa formulir. Setiap formulir adalah instruksi yang memberi tahu jaringan apa yang harus dilakukan. Mengirim transaksi seperti mengirimkan amplop agar formulir dapat diproses.
Contoh di bawah ini menunjukkan versi sederhana dari dua transaksi. Ketika transaksi pertama diproses, transaksi akan mengeksekusi satu instruksi. Ketika transaksi kedua diproses, transaksi akan mengeksekusi tiga instruksi secara berurutan: pertama instruksi 1, diikuti oleh instruksi 2, diikuti oleh instruksi 3.
Transaksi bersifat atomik: Jika satu instruksi gagal, seluruh transaksi akan gagal dan tidak ada perubahan yang akan terjadi.
Diagram sederhana yang menunjukkan dua transaksi
Sebuah
Transaction
terdiri dari informasi berikut:
signatures: Array dari tanda tanganmessage: Informasi transaksi, termasuk daftar instruksi yang akan diproses
Transaction
pub struct Transaction {#[wasm_bindgen(skip)]#[serde(with = "short_vec")]pub signatures: Vec<Signature>,#[wasm_bindgen(skip)]pub message: Message,}
Diagram yang menunjukkan dua bagian dari transaksi
Transaksi memiliki batas ukuran total
1232
byte. Batas ini mencakup baik array signatures maupun struct
message.
Batas ini berasal dari ukuran Maximum Transmission Unit (MTU) IPv6 sebesar 1280 byte, dikurangi 48 byte untuk header jaringan (40 byte IPv6 + 8 byte header).
Diagram yang menunjukkan format transaksi dan batas ukuran
Tanda Tangan
Array signatures pada transaksi berisi struct Signature. Setiap
Signature
berukuran 64 byte dan dibuat dengan menandatangani Message transaksi dengan
kunci privat akun. Tanda tangan harus disediakan untuk setiap
akun penandatangan yang disertakan pada instruksi
transaksi.
Tanda tangan pertama milik akun yang akan membayar biaya dasar transaksi dan merupakan tanda tangan transaksi. Tanda tangan transaksi dapat digunakan untuk mencari detail transaksi di jaringan.
Pesan
message transaksi adalah struktur
Message
yang berisi informasi berikut:
header: Header pesanaccount_keys: Array alamat akun yang diperlukan oleh instruksi transaksirecent_blockhash: Blockhash yang bertindak sebagai stempel waktu untuk transaksiinstructions: Array instruksi
Untuk menghemat ruang, transaksi tidak menyimpan izin untuk setiap akun secara
individual. Sebagai gantinya, izin akun ditentukan menggunakan header dan
account_keys.
Message
pub struct Message {/// The message header, identifying signed and read-only `account_keys`.pub header: MessageHeader,/// All the account keys used by this transaction.#[serde(with = "short_vec")]pub account_keys: Vec<Pubkey>,/// The id of a recent ledger entry.pub recent_blockhash: Hash,/// Programs that will be executed in sequence and committed in/// one atomic transaction if all succeed.#[serde(with = "short_vec")]pub instructions: Vec<CompiledInstruction>,}
Header
header pesan adalah struktur
MessageHeader.
Ini berisi informasi berikut:
num_required_signatures: Jumlah total tanda tangan yang diperlukan oleh transaksinum_readonly_signed_accounts: Jumlah total akun hanya-baca yang memerlukan tanda tangannum_readonly_unsigned_accounts: Jumlah total akun hanya-baca yang tidak memerlukan tanda tangan
MessageHeader
pub struct MessageHeader {/// The number of signatures required for this message to be considered/// valid. The signers of those signatures must match the first/// `num_required_signatures` of [`Message::account_keys`].pub num_required_signatures: u8,/// The last `num_readonly_signed_accounts` of the signed keys are read-only/// accounts.pub num_readonly_signed_accounts: u8,/// The last `num_readonly_unsigned_accounts` of the unsigned keys are/// read-only accounts.pub num_readonly_unsigned_accounts: u8,}
Diagram yang menunjukkan tiga bagian header pesan
Alamat akun
account_keys
pesan adalah array alamat akun, dikirim dalam
format array kompak. Awalan
array menunjukkan panjangnya. Setiap item dalam array adalah kunci publik, yang
menunjuk ke akun yang digunakan oleh instruksinya. Array accounts_keys harus
lengkap, dan diurutkan secara ketat, sebagai berikut:
- Penandatangan + Dapat ditulis
- Penandatangan + Hanya-baca
- Bukan penandatangan + Dapat ditulis
- Bukan penandatangan + Hanya-baca
Pengurutan yang ketat memungkinkan array account_keys dikombinasikan dengan
informasi dalam header pesan untuk menentukan izin untuk setiap
akun.
Diagram menunjukkan urutan array alamat akun
Blockhash terbaru
recent_blockhash pada pesan adalah nilai hash yang berfungsi sebagai stempel
waktu transaksi dan mencegah duplikasi transaksi. Sebuah blockhash kedaluwarsa
setelah
150 blok.
(Setara dengan satu menit—dengan asumsi setiap blok adalah 400ms.) Setelah blok
kedaluwarsa, transaksi tersebut juga kedaluwarsa dan tidak dapat diproses.
Metode RPC getLatestBlockhash
memungkinkan Anda mendapatkan blockhash terkini dan tinggi blok terakhir di
mana blockhash tersebut akan tetap valid.
Instruksi
instructions
pada pesan adalah array dari semua instruksi yang akan diproses, dikirim dalam
format array kompak. Awalan
array menunjukkan panjangnya. Setiap item dalam array adalah struktur
CompiledInstruction
dan mencakup informasi berikut:
program_id_index: Indeks yang menunjuk ke alamat dalam arrayaccount_keys. Nilai ini menunjukkan alamat program yang memproses instruksi.accounts: Array indeks yang menunjuk ke alamat dalam arrayaccount_keys. Setiap indeks menunjuk ke alamat akun yang diperlukan untuk instruksi ini.data: Array byte yang menentukan instruksi mana yang akan dipanggil pada program. Ini juga mencakup data tambahan yang diperlukan oleh instruksi. (Misalnya, argumen fungsi)
CompiledInstruction
pub struct CompiledInstruction {/// Index into the transaction keys array indicating the program account that executes this instruction.pub program_id_index: u8,/// Ordered indices into the transaction keys array indicating which accounts to pass to the program.#[serde(with = "short_vec")]pub accounts: Vec<u8>,/// The program input data.#[serde(with = "short_vec")]pub data: Vec<u8>,}
Array kompak dari Instruksi
Contoh struktur transaksi
Contoh berikut menunjukkan struktur transaksi yang berisi satu instruksi transfer SOL.
import {createSolanaRpc,generateKeyPairSigner,lamports,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,appendTransactionMessageInstructions,pipe,signTransactionMessageWithSigners,getCompiledTransactionMessageDecoder} from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";const rpc = createSolanaRpc("http://localhost:8899");const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();// 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});// Create transaction messageconst transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(sender, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions([transferInstruction], tx));const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);// Decode the messageBytesconst compiledTransactionMessage =getCompiledTransactionMessageDecoder().decode(signedTransaction.messageBytes);console.log(JSON.stringify(compiledTransactionMessage, null, 2));
Console
Click to execute the code.
Kode di bawah ini menunjukkan output dari cuplikan kode sebelumnya. Format berbeda antara SDK, tetapi perhatikan bahwa setiap instruksi berisi informasi yang sama yang diperlukan.
{"version": 0,"header": {"numSignerAccounts": 1,"numReadonlySignerAccounts": 0,"numReadonlyNonSignerAccounts": 1},"staticAccounts": ["HoCy8p5xxDDYTYWEbQZasEjVNM5rxvidx8AfyqA4ywBa","5T388jBjovy7d8mQ3emHxMDTbUF8b7nWvAnSiP3EAdFL","11111111111111111111111111111111"],"lifetimeToken": "EGCWPUEXhqHJWYBfDirq3mHZb4qDpATmYqBZMBy9TBC1","instructions": [{"programAddressIndex": 2,"accountIndices": [0, 1],"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}}]}
Setelah transaksi dikirimkan, Anda dapat mengambil detailnya menggunakan tanda tangan transaksi dan metode RPC getTransaction. Responsnya akan memiliki struktur yang mirip dengan cuplikan berikut.
Anda juga dapat menemukan transaksi menggunakan Solana Explorer.
Transaction Data
{"blockTime": 1745196488,"meta": {"computeUnitsConsumed": 150,"err": null,"fee": 5000,"innerInstructions": [],"loadedAddresses": {"readonly": [],"writable": []},"logMessages": ["Program 11111111111111111111111111111111 invoke [1]","Program 11111111111111111111111111111111 success"],"postBalances": [989995000, 10000000, 1],"postTokenBalances": [],"preBalances": [1000000000, 0, 1],"preTokenBalances": [],"rewards": [],"status": {"Ok": null}},"slot": 13049,"transaction": {"message": {"header": {"numReadonlySignedAccounts": 0,"numReadonlyUnsignedAccounts": 1,"numRequiredSignatures": 1},"accountKeys": ["8PLdpLxkuv9Nt8w3XcGXvNa663LXDjSrSNon4EK7QSjQ","7GLg7bqgLBv1HVWXKgWAm6YoPf1LoWnyWGABbgk487Ma","11111111111111111111111111111111"],"recentBlockhash": "7ZCxc2SDhzV2bYgEQqdxTpweYJkpwshVSDtXuY7uPtjf","instructions": [{"accounts": [0, 1],"data": "3Bxs4NN8M2Yn4TLb","programIdIndex": 2,"stackHeight": null}],"indexToProgramIds": {}},"signatures": ["3jUKrQp1UGq5ih6FTDUUt2kkqUfoG2o4kY5T1DoVHK2tXXDLdxJSXzuJGY4JPoRivgbi45U2bc7LZfMa6C4R3szX"]},"version": "legacy"}
Is this page helpful?