İşlemler

Solana ağıyla etkileşim kurmak için bir işlem göndermeniz gerekir. Bir işlemi, içinde birkaç form bulunan bir zarf olarak düşünebilirsiniz. Her form, ağa ne yapması gerektiğini söyleyen bir talimattır. İşlemi göndermek, formların işlenebilmesi için zarfı postalamak gibidir.

Aşağıdaki örnek, iki işlemin basitleştirilmiş bir versiyonunu göstermektedir. İlk işlem işlendiğinde, tek bir talimatı yürütecektir. İkinci işlem işlendiğinde, sıralı olarak üç talimatı yürütecektir: önce talimat 1, ardından talimat 2, ardından talimat 3.

İşlemler atomiktir: Tek bir talimat başarısız olursa, tüm işlem başarısız olur ve hiçbir değişiklik gerçekleşmez.

İki işlemi gösteren basitleştirilmiş bir diyagramİki işlemi gösteren basitleştirilmiş bir diyagram

Bir Transaction aşağıdaki bilgilerden oluşur:

  • signatures: İmzalar dizisi
  • message: İşlenecek talimatlar listesi dahil işlem bilgileri
Transaction
pub struct Transaction {
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub signatures: Vec<Signature>,
#[wasm_bindgen(skip)]
pub message: Message,
}

Bir işlemin iki parçasını gösteren diyagramBir işlemin iki parçasını gösteren diyagram

İşlemlerin toplam boyut sınırı 1232 bayttır. Bu sınır hem signatures dizisini hem de message yapısını içerir.

Bu sınır, IPv6 Maksimum İletim Birimi (MTU) boyutu olan 1280 bayttan, ağ başlıkları için 48 bayt (40 bayt IPv6 + 8 bayt başlık) çıkarılarak elde edilir.

İşlem formatını ve boyut sınırlarını gösteren diyagramİşlem formatını ve boyut sınırlarını gösteren diyagram

İmzalar

İşlemin signatures dizisi Signature yapılarını içerir. Her Signature 64 bayttır ve işlemin Message'ını hesabın özel anahtarıyla imzalayarak oluşturulur. İşlemin talimatlarında yer alan her imzalayıcı hesap için bir imza sağlanmalıdır.

İlk imza, işlemin temel ücretini ödeyecek hesaba aittir ve işlem imzasıdır. İşlem imzası, ağ üzerinde işlemin ayrıntılarını aramak için kullanılabilir.

Mesaj

İşlemin message kısmı, aşağıdaki bilgileri içeren bir Message yapısıdır:

Alandan tasarruf etmek için, işlem her hesap için izinleri ayrı ayrı saklamaz. Bunun yerine, hesap izinleri header ve account_keys kullanılarak belirlenir.

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

Başlık

Mesajın header kısmı bir MessageHeader yapısıdır. Aşağıdaki bilgileri içerir:

  • num_required_signatures: İşlem için gereken toplam imza sayısı
  • num_readonly_signed_accounts: İmza gerektiren salt okunur hesapların toplam sayısı
  • num_readonly_unsigned_accounts: İmza gerektirmeyen salt okunur hesapların toplam sayısı
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,
}

Mesaj başlığının üç bölümünü gösteren diyagramMesaj başlığının üç bölümünü gösteren diyagram

Hesap adresleri

Mesajın account_keys kısmı, kompakt dizi formatında gönderilen hesap adreslerinin bir dizisidir. Dizinin öneki uzunluğunu belirtir. Dizideki her öğe, talimatları tarafından kullanılan bir hesaba işaret eden bir genel anahtardır. accounts_keys dizisi eksiksiz ve aşağıdaki gibi kesin bir şekilde sıralanmış olmalıdır:

  1. İmzalayan + Yazılabilir
  2. İmzalayan + Salt okunur
  3. İmzalamayan + Yazılabilir
  4. İmzalamayan + Salt okunur

Kesin sıralama, account_keys dizisinin mesajın header kısmındaki bilgilerle birleştirilerek her hesap için izinlerin belirlenmesine olanak tanır.

Hesap adresleri dizisinin sırasını gösteren diyagramHesap adresleri dizisinin sırasını gösteren diyagram

Son blok hash değeri

Mesajın recent_blockhash değeri, işlem için bir zaman damgası görevi gören ve yinelenen işlemleri önleyen bir hash değeridir. Bir blok hash değeri 150 blok sonra sona erer. (Her bloğun 400ms olduğu varsayılarak yaklaşık bir dakikaya eşdeğerdir.) Blok süresi dolduktan sonra, işlem sona erer ve işlenemez.

getLatestBlockhash RPC metodu, mevcut blok hash değerini ve blok hash değerinin geçerli olacağı son blok yüksekliğini almanıza olanak tanır.

Talimatlar

Mesajın instructions değeri, işlenecek tüm talimatların kompakt dizi formatında gönderilen bir dizisidir. Dizinin öneki uzunluğunu belirtir. Dizideki her öğe bir CompiledInstruction yapısıdır ve aşağıdaki bilgileri içerir:

  1. program_id_index: account_keys dizisindeki bir adrese işaret eden bir indeks. Bu değer, talimatı işleyen programın adresini gösterir.
  2. accounts: account_keys dizisindeki adreslere işaret eden indekslerin bir dizisi. Her indeks, bu talimat için gerekli bir hesabın adresine işaret eder.
  3. data: Programda hangi talimatın çağrılacağını belirten bir bayt dizisi. Ayrıca talimat tarafından gereken ek verileri de içerir. (Örneğin, fonksiyon argümanları)
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>,
}

Talimatların kompakt dizisiTalimatların kompakt dizisi

Örnek işlem yapısı

Aşağıdaki örnek, tek bir SOL transfer talimatı içeren bir işlemin yapısını göstermektedir.

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.

Aşağıdaki kod, önceki kod parçacıklarından elde edilen çıktıyı göstermektedir. Format SDK'lar arasında farklılık gösterir, ancak her talimatın aynı gerekli bilgileri içerdiğine dikkat edin.

{
"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
}
}
]
}

Bir işlem gönderildikten sonra, işlem imzasını ve getTransaction RPC yöntemini kullanarak ayrıntılarını alabilirsiniz. Yanıt, aşağıdaki kod parçasına benzer bir yapıya sahip olacaktır.

İşlemi Solana Explorer kullanarak da bulabilirsiniz.

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?

İçindekiler

Sayfayı Düzenle

Yönetici

© 2025 Solana Vakfı.
Tüm hakları saklıdır.
Bağlanın