İş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
Bir Transaction aşağıdaki bilgilerden oluşur:
- signatures: İmzalar dizisi
- message: İşlenecek talimatlar listesi dahil işlem bilgileri
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 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
İ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:
header: Mesaj başlığıaccount_keys: İşlemin talimatları tarafından gereken hesap adreslerinin bir dizisirecent_blockhash: İşlem için zaman damgası görevi gören bir blok hash'iinstructions: Talimatların bir dizisi
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.
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ı
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 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:
- İmzalayan + Yazılabilir
- İmzalayan + Salt okunur
- İmzalamayan + Yazılabilir
- İ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 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:
program_id_index:account_keysdizisindeki bir adrese işaret eden bir indeks. Bu değer, talimatı işleyen programın adresini gösterir.accounts:account_keysdizisindeki adreslere işaret eden indekslerin bir dizisi. Her indeks, bu talimat için gerekli bir hesabın adresine işaret eder.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ı)
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 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 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));
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.
{"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?