Talimatlar, Solana blok zinciriyle etkileşim kurmanın temel yapı taşıdır. Bir talimat, esasen Solana ağını kullanan herkesin çağırabileceği genel bir fonksiyondur. Her talimat belirli bir eylemi gerçekleştirmek için kullanılır. Talimatların yürütme mantığı programlarda saklanır ve her program kendi talimat setini tanımlar. Solana ağıyla etkileşim kurmak için, bir veya daha fazla talimat bir işleme eklenir ve işlenmek üzere ağa gönderilir.
SOL transfer örneği
Aşağıdaki diyagram, işlemlerin ve talimatların kullanıcıların ağla etkileşim kurmasına nasıl olanak sağladığını göstermektedir. Bu örnekte, SOL bir hesaptan diğerine transfer edilir.
Gönderen hesabın meta verileri, işlem için imza atması gerektiğini belirtir. (Bu, System Program'ın lamport düşmesine izin verir.) Hem gönderen hem de alıcı hesapların, lamport bakiyelerinin değişebilmesi için yazılabilir olması gerekir. Bu talimatı yürütmek için, gönderenin cüzdanı imzasını ve SOL transfer talimatını içeren mesajı içeren işlemi gönderir.
SOL transfer diyagramı
İşlem gönderildikten sonra, System Program transfer talimatını işler ve her iki hesabın da lamport bakiyesini günceller.
SOL transfer işlem diyagramı
Aşağıdaki örnek, yukarıdaki diyagramlarla ilgili kodu göstermektedir. (System Program'ın transfer talimatına bakın.)
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);
Talimatlar
Bir talimat içeren bir işlemi ve 3 bileşenine ayrılmış halini gösteren diyagram
Bir
Instruction
aşağıdaki bilgilerden oluşur:
program_id: Çağrılan programın ID'si.accounts: Hesap metadatası dizisidata: Talimat tarafından kullanılacak ek [veri] içeren bayt dizisi.
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
Talimatın program_id'si, talimatın
iş mantığını içeren programın public key adresidir.
Hesap meta verileri
Talimatın accounts dizisi,
AccountMeta
struct'larından oluşan bir dizidir. Talimatın etkileşimde bulunduğu her hesap
için metadata sağlanmalıdır. (Bu, aynı hesabı değiştirmedikleri sürece
transaction'ların talimatları paralel olarak yürütmesine olanak tanır.)
Aşağıdaki diyagram, tek bir talimat içeren bir transaction'ı göstermektedir.
Talimatın accounts dizisi iki hesap için metadata içerir.
Tek talimatlı bir transaction. Talimat, accounts dizisinde iki AccountMeta struct'ı içerir.
Hesap meta verileri aşağıdaki bilgileri içerir:
- pubkey: Hesabın public key adresi
- is_signer: Hesap transaction'ı imzalamalıysa
trueolarak ayarlanır - is_writable: Talimat hesabın verisini değiştiriyorsa
trueolarak ayarlanır
Bir talimatın hangi hesapları gerektirdiğini, hangilerinin yazılabilir, salt okunur olması gerektiğini veya işlemi imzalaması gerektiğini bilmek için, program tarafından tanımlandığı şekilde talimatın uygulamasına başvurmanız gerekir.
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,}
Veri
Talimatın data'sı, programın hangi talimatının çağrılacağını belirten bir bayt
dizisidir. Ayrıca talimatın gerektirdiği tüm argümanları içerir.
Talimat oluşturma örneği
Aşağıdaki örnek, bir SOL transfer talimatının yapısını göstermektedir.
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));
Aşağıdaki kod, önceki kod parçacıklarının çıktısını göstermektedir. Format
SDK'lar arasında farklılık gösterecektir, ancak her talimatın aynı üç gerekli
bilgiyi içerdiğine dikkat edin: 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}}
Aşağıdaki örnekler, transfer talimatının manuel olarak nasıl oluşturulacağını
göstermektedir. (Expanded Instruction sekmesi, Instruction sekmesiyle
işlevsel olarak eşdeğerdir.)
Pratikte, genellikle bir Instruction manuel olarak oluşturmanız gerekmez.
Çoğu program, talimatları sizin için oluşturan yardımcı fonksiyonlara sahip
istemci kütüphaneleri sağlar. Bir kütüphane mevcut değilse, talimatı manuel
olarak oluşturabilirsiniz.
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?