Talimatlar
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);
Console
Click to execute the code.
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 meta verileri dizisidata
: Talimat tarafından kullanılacak ek [veri] içeren bir bayt dizisi.
Instruction struct
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
, talimatın iş
mantığını içeren programın pubkey adresidir.
Hesap meta verileri
Talimatın accounts
dizisi, bir
AccountMeta
yapıları dizisidir. Talimatın etkileşimde bulunduğu her hesap için meta veri
sağlanmalıdır. (Bu, aynı hesabı değiştirmedikleri sürece, işlemlerin talimatları
paralel olarak yürütmesine olanak tanır.)
Aşağıdaki diyagram, tek bir talimat içeren bir işlemi göstermektedir. Talimatın
accounts
dizisi, iki hesap için meta veri içerir.
Bir talimat içeren bir işlem. Talimat, accounts dizisinde iki AccountMeta yapısı içerir.
Hesap meta verileri aşağıdaki bilgileri içerir:
- pubkey: Hesabın pubkey adresi
- is_signer: Hesabın işlemi imzalaması gerekiyorsa
true
olarak ayarlanır - is_writable: Talimat hesabın verilerini değiştiriyorsa
true
olarak 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.
AccountMeta
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
kısmı, programın hangi talimatının çağrılacağını belirten bir
bayt dizisidir. Ayrıca talimat tarafından gerektirilen argümanları da 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));
Console
Click to execute the code.
Aşağıdaki kod, önceki kod parçalarından elde edilen çıktıyı göstermektedir.
Format SDK'lar arasında farklılık gösterebilir, ancak her talimatın aynı üç
gerekli bilgi parçasını 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ı manuel olarak nasıl oluşturacağınızı
göstermektedir. (Expanded Instruction
sekmesi, işlevsel olarak Instruction
sekmesine eşdeğerdir.)
Pratikte, genellikle bir Instruction
talimatını 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. Eğer 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?