ملخص
تحتوي التعليمات على 3 حقول: program_id (أي برنامج يتم استدعاؤه)، accounts
(قائمة AccountMeta مع علامات is_signer/is_writable)، و data (مصفوفة بايتات
من البيانات التي يفسرها البرنامج).
بنية التعليمات
تتكون
Instruction
من ثلاثة حقول:
program_id: معرف البرنامج الذي يتم استدعاؤه.accounts: مصفوفة من بيانات الحساب الوصفيةdata: مصفوفة بايتات تحتوي على بيانات إضافية لاستخدامها بواسطة التعليمات.
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 الخاصة بها.
تحتوي كل بنية AccountMeta على ثلاثة حقول:
- pubkey: عنوان المفتاح العام للحساب
- is_signer: يتم تعيينها إلى
trueإذا كان يجب على الحساب التوقيع على المعاملة - is_writable: يتم تعيينها إلى
trueإذا كانت التعليمات تعدل بيانات الحساب
لمعرفة الحسابات التي يتطلبها التعليم، بما في ذلك أيها يجب أن يكون قابلاً للكتابة أو للقراءة فقط أو يوقع المعاملة، يجب عليك الرجوع إلى تنفيذ التعليم كما هو محدد بواسطة البرنامج.
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 الخاص بالتعليم هو مصفوفة بايتات تخبر البرنامج بالدالة التي يجب
استدعاؤها وتوفر الوسائط لتلك الدالة. تبدأ البيانات عادةً بمميز أو بايت(ات) فهرس
يحدد الدالة المستهدفة، متبوعاً بالوسائط المتسلسلة. يتم تحديد تنسيق الترميز
بواسطة كل برنامج (على سبيل المثال، تسلسل Borsh أو تخطيط مخصص).
اصطلاحات الترميز الشائعة:
- البرامج الأساسية (System، Stake، Vote): تستخدم فهرس متغير enum متسلسل بـ Bincode متبوعاً بوسائط متسلسلة.
- برامج Anchor: تستخدم مميزاً من 8 بايتات (أول 8 بايتات من تجزئة SHA-256 لـ
"global:<function_name>") متبوعاً بوسائط متسلسلة بـ Borsh.
وقت التشغيل لا يفسر حقل data. يتم تمريره كما هو إلى نقطة دخول
process_instruction الخاصة بالبرنامج.
التعليم المترجم
عندما يتم تسلسل التعليمات في رسالة معاملة، تصبح بنى
CompiledInstruction
التي تستبدل جميع المفاتيح العامة بفهارس أعداد صحيحة مدمجة في مصفوفة
account_keys الخاصة بالرسالة.
مثال: تعليم تحويل SOL
يوضح المثال أدناه بنية تعليم تحويل 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));
يوضح الكود أدناه المخرجات من مقتطفات الكود السابقة. سيختلف التنسيق بين 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?