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 transaksiDiagram sederhana yang menunjukkan dua transaksi

Sebuah Transaction terdiri dari informasi berikut:

  • signatures: Array dari tanda tangan
  • message: 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 transaksiDiagram 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 ukuranDiagram 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 pesan
  • account_keys: Array alamat akun yang diperlukan oleh instruksi transaksi
  • recent_blockhash: Blockhash yang bertindak sebagai stempel waktu untuk transaksi
  • instructions: 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 pesan adalah struktur MessageHeader. Ini berisi informasi berikut:

  • num_required_signatures: Jumlah total tanda tangan yang diperlukan oleh transaksi
  • num_readonly_signed_accounts: Jumlah total akun hanya-baca yang memerlukan tanda tangan
  • num_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 pesanDiagram 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:

  1. Penandatangan + Dapat ditulis
  2. Penandatangan + Hanya-baca
  3. Bukan penandatangan + Dapat ditulis
  4. 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 akunDiagram 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:

  1. program_id_index: Indeks yang menunjuk ke alamat dalam array account_keys. Nilai ini menunjukkan alamat program yang memproses instruksi.
  2. accounts: Array indeks yang menunjuk ke alamat dalam array account_keys. Setiap indeks menunjuk ke alamat akun yang diperlukan untuk instruksi ini.
  3. 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 InstruksiArray 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 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
});
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(sender, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions([transferInstruction], tx)
);
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Decode the messageBytes
const 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?

Daftar Isi

Edit Halaman

Dikelola oleh

© 2025 Yayasan Solana.
Semua hak dilindungi.
Transaksi | Solana