التعليمات
التعليمات هي اللبنة الأساسية للتفاعل مع بلوكتشين سولانا. التعليمة هي في الأساس دالة عامة يمكن لأي شخص يستخدم شبكة سولانا استدعاؤها. تُستخدم كل تعليمة لتنفيذ إجراء محدد. يتم تخزين منطق تنفيذ التعليمات في البرامج، حيث يحدد كل برنامج مجموعته الخاصة من التعليمات. للتفاعل مع شبكة سولانا، يتم إضافة تعليمة واحدة أو أكثر إلى معاملة وإرسالها إلى الشبكة لمعالجتها.
مثال على تحويل SOL
يوضح الرسم البياني أدناه كيف تعمل المعاملات والتعليمات معًا للسماح للمستخدمين بالتفاعل مع الشبكة. في هذا المثال، يتم تحويل SOL من حساب إلى آخر.
تشير بيانات التعريف لحساب المرسل إلى أنه يجب عليه التوقيع على المعاملة. (هذا يسمح للبرنامج النظام بخصم لامبورت.) يجب أن يكون كل من حساب المرسل والمستلم قابلين للكتابة، حتى يتمكن رصيد اللامبورت الخاص بهما من التغيير. لتنفيذ هذه التعليمة، ترسل محفظة المرسل المعاملة التي تحتوي على توقيعها والرسالة التي تحتوي على تعليمة تحويل SOL.
رسم بياني لتحويل SOL
بعد إرسال المعاملة، يقوم System Program بمعالجة تعليمة التحويل وتحديث رصيد اللامبورت لكلا الحسابين.
رسم بياني لعملية تحويل SOL
يوضح المثال أدناه الكود المتعلق بالرسوم البيانية أعلاه. (انظر تعليمة التحويل الخاصة بـ System Program.)
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.
التعليمات
رسم بياني يوضح معاملة تحتوي على تعليمة، مقسمة إلى 3 مكونات
تتكون
Instruction
من المعلومات التالية:
program_id
: معرّف البرنامج الذي يتم استدعاؤه.accounts
: مصفوفة من بيانات وصفية للحسابdata
: مصفوفة بايت تحتوي على [بيانات] إضافية لاستخدامها بواسطة التعليمة.
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
الخاص بالتعليمة هو عنوان
المفتاح العام للبرنامج الذي يحتوي على منطق الأعمال للتعليمة.
البيانات الوصفية للحساب
مصفوفة accounts
الخاصة بالتعليمة هي مصفوفة من هياكل
AccountMeta
.
يجب توفير البيانات الوصفية لكل حساب تتفاعل معه التعليمة. (هذا يسمح للمعاملة
بتنفيذ التعليمات بالتوازي، طالما أنها لا تقوم بتعديل نفس الحساب.)
يوضح الرسم البياني أدناه معاملة تحتوي على تعليمة واحدة. تحتوي مصفوفة accounts
الخاصة بالتعليمة على بيانات وصفية لحسابين.
معاملة بتعليمة واحدة. تحتوي التعليمة على هيكلين من نوع AccountMeta في مصفوفة accounts الخاصة بها.
تتضمن البيانات الوصفية للحساب المعلومات التالية:
- pubkey: عنوان المفتاح العام للحساب
- is_signer: يتم تعيينه إلى
true
إذا كان يجب على الحساب التوقيع على المعاملة - is_writable: يتم تعيينه إلى
true
إذا كانت التعليمة تقوم بتعديل بيانات الحساب
لمعرفة الحسابات التي تتطلبها التعليمة، بما في ذلك تلك التي يجب أن تكون قابلة للكتابة، أو للقراءة فقط، أو التي يجب أن توقع على المعاملة، يجب عليك الرجوع إلى تنفيذ التعليمة، كما هو محدد بواسطة البرنامج.
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,}
البيانات
data
الخاصة بالتعليمة هي مصفوفة بايت تحدد أي من تعليمات البرنامج سيتم
استدعاؤها. كما تتضمن أي وسائط مطلوبة بواسطة التعليمة.
مثال على إنشاء تعليمة
يوضح المثال أدناه بنية تعليمة تحويل SOL.
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.
يوضح الكود أدناه المخرجات من مقتطفات الكود السابقة. قد يختلف التنسيق بين مجموعات
تطوير البرمجيات (SDKs)، ولكن لاحظ أن كل تعليمة تحتوي على نفس المعلومات الثلاثة
المطلوبة: 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}}
توضح الأمثلة أدناه كيفية بناء تعليمة التحويل يدويًا. (علامة التبويب
Expanded Instruction
مكافئة وظيفيًا لعلامة التبويب Instruction
)
في الواقع العملي، عادةً لا تحتاج إلى إنشاء Instruction
يدويًا. توفر معظم
البرامج مكتبات عميلة مع دوال مساعدة تقوم بإنشاء التعليمات نيابة عنك. إذا لم
تكن هناك مكتبة متاحة، يمكنك بناء التعليمة يدويًا.
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?