تم إنشاء هذه المقالة بواسطة الذكاء الاصطناعي. يرجى التحقق من المعلومات المهمة بشكل مستقل.

دليل إطار عمل Solana Anchor

Crypto Wiki|Oct 8, 2026|★★★★★★4.5 (500 تقييمات)
ملخص الذكاء الاصطناعي

Learn to build Solana programs with Anchor Framework. Complete guide covering setup, core concepts, security, testing and deployment to devnet.

يساعد إطار عمل Solana Anchor المطورين على بناء برامج مع التحقق المنظم للحسابات، وتعريفات التعليمات، والواجهات المولدة، وضمانات الأمان القابلة لإعادة الاستخدام.

ملاحظة الإصدار: تتغير إصدارات Anchor، و Rust، و Solana CLI، وعميل JavaScript بشكل مستقل. تحقق من التوافق الحالي في وثائق Anchor الرسمية قبل التثبيت أو النشر.

هذا المقال لأغراض تعليمية فقط ولا يشكل نصيحة مالية أو استثمارية. استثمارات العملات الرقمية تحمل مخاطر كبيرة. قم دائمًا بإجراء بحثك الخاص قبل اتخاذ قرارات الاستثمار.

📌 ملاحظة: يستخدم هذا الدليل Anchor v0.29.x و Solana CLI v1.18.x+، وهو الحالي اعتبارًا من عام 2024. يتطور إطار عمل Anchor بسرعة. قم بتشغيل anchor --version للتحقق من إصدارك المثبت قبل اتباع هذه التعليمات.


جدول المحتويات

  1. ما هو إطار عمل Solana Anchor؟
  2. نموذج حسابات Solana
  3. المكونات الأساسية لإطار عمل Solana Anchor
  4. المتطلبات المسبقة
  5. كيفية تثبيت إطار عمل Anchor
  6. بناء ونشر أول برنامج Anchor خاص بك
  7. اختبار برامج Anchor
  8. Anchor مقابل البدائل
  9. أمان إطار عمل Anchor
  10. استكشاف أخطاء Anchor الشائعة وإصلاحها
  11. إطار عمل Anchor وبيئة تطوير Solana
  12. أسئلة متكررة
  13. خاتمة

ما هو إطار عمل Solana Anchor؟

إطار عمل Solana Anchor هو إطار عمل تطوير مفتوح المصدر يلغي الحاجة إلى كتابة تعليمات برمجية متكررة ومعقدة للتحقق من الحسابات عند كتابة برامج Solana (المعادل داخل الكتلة للعقود الذكية) بلغة Rust الخام.

Solana هي بلوكتشين من الطبقة 1 عالية الأداء تعالج حوالي 65,000 معاملة في الثانية في ظل الظروف المثلى (اعتبارًا من عام 2024)، مع نهائية أقل من ثانية ورسوم عادةً أقل من 0.001 دولار. تحقق Solana هذه الإنتاجية جزئيًا من خلال آلية توافق فريدة تسمى إثبات التاريخ (PoH)، والتي تنشئ ساعة تشفير ترتب المعاملات دون حمل الاتصال الزائد لبروتوكولات التوافق التقليدية.

يتطلب البناء على Solana بدون إطار عمل كتابة تعليمات برمجية verbose، منخفضة المستوى بلغة Rust لكل برنامج. يجب على المطورين التحقق يدويًا من ملكية الحساب، وتسلسل البيانات، ومعالجة الأخطاء، وإدارة علاقات الحسابات لكل معاملة فردية. بالنسبة للمهندسين القادمين من خلفيات Web2 أو تطوير Ethereum، فإن جدار التعلم هذا مرتفع بما يكفي لإيقاف معظم المشاريع قبل أن تبدأ.

Anchor يغير ذلك. فكر في Anchor على أنه Ruby on Rails لتطوير Solana: إطار عمل متعصب يتعامل مع السباكة حتى تتمكن من التركيز على منطق برنامجك بدلاً من البنية التحتية الأساسية له. تم إنشاء Anchor بواسطة Armani Ferrante ويتم صيانته بواسطة Coral XYZ. يمكنك العثور على الكود المصدري والإصدارات في مستودع GitHub الخاص بـ Anchor (coral-xyz/anchor).) الإصدار المستقر الحالي هو v0.29.x.

يمكّن Anchor المطورين من بناء تطبيقات لامركزية (dApps). التطبيق اللامركزي هو تطبيق يعمل منطق الخلفية الخاص به على بلوكتشين عبر برامج Solana بدلاً من خادم مركزي. البرنامج هو الواجهة الخلفية للتطبيق اللامركزي؛ العميل TypeScript الذي ينشئه Anchor هو كيفية استدعاء الواجهة الأمامية له. تشمل فئات التطبيقات اللامركزية المبنية باستخدام Anchor بروتوكولات التمويل اللامركزي (DeFi)، ومنصات الرموز غير القابلة للاستبدال (NFT)، والمنظمات اللامركزية المستقلة (DAOs)، وألعاب Web3.

بنهاية هذا الدليل، ستفهم الهندسة المعمارية الأساسية لـ Anchor، وستحصل على بيئة تطوير عاملة، وستكون قد نشرت برنامجًا على شبكة التطوير الخاصة بـ Solana (شبكة اختبار بها SOL مجاني وبدون قيمة)، وسيكون لديك سياق كافٍ لتقييم ما إذا كان Anchor يناسب مشروعك. للحصول على نظرة مباشرة حول كيفية مقارنة Anchor بأدوات Ethereum والتطوير الخام بلغة Rust، راجع كيف يقارن Anchor بأدوات Hardhat الخاصة بـ Ethereum والتطوير الخام بلغة Rust.

ما ستتعلمه:

  • ما هي Solana ولماذا تجعل هندستها المعمارية Anchor ضروريًا
  • ما الذي يفعله كل من IDL، والوحدات الماكرو، وPDAs، وكيف تتصل البرامج ببعضها البعض
  • كيفية تثبيت بيئة تطوير Anchor الكاملة
  • كيفية كتابة ونشر أول برنامج Anchor خاص بك
  • ثغرات أمنية يجب تجنبها قبل الشحن إلى المينيت
  • كيفية استكشاف أخطاء Anchor الأكثر شيوعًا وإصلاحها

نموذج حسابات Solana: الأساس الذي تحتاج إلى فهمه أولاً

نموذج حسابات Solana هو الأساس المعماري الذي يجعل Anchor ضروريًا. إنه مختلف حقًا عن أي شيء تواجهه في تطوير Ethereum أو Web2. قبل أن تصبح تجريدات Anchor منطقية، تحتاج إلى فهم المشكلة التي تحلها.

ما هي Solana

Solana هي شبكة بلوكتشين من الطبقة 1 مصممة لتحقيق إنتاجية عالية وتكاليف معاملات منخفضة. على عكس Ethereum، التي تعالج حوالي 15 إلى 30 معاملة في الثانية على المينيت، تعالج Solana حوالي 65,000 معاملة في الثانية في ظل الظروف المثلى (اعتبارًا من عام 2024). تقع رسوم المعاملات عادةً أقل من 0.001 دولار. هذا المزيج من السرعة والتكلفة يجعل Solana مناسبة تمامًا للتطبيقات التي تتطلب العديد من المعاملات الصغيرة والمتكررة: أنظمة التداول (DeFi)، ومنصات سك الرموز غير القابلة للاستبدال (NFT)، والألعاب داخل الكتلة.

SOL هو الرمز الأصلي لـ Solana. يدفع رسوم المعاملات وتكاليف الإيجار التي يجب أن تحتفظ بها الحسابات داخل الكتلة لتبقى نشطة على الشبكة. كل برنامج تقوم بنشره وكل حساب ينشئه برنامجك يتطلب SOL ليوجد داخل الكتلة. على شبكة التطوير (شبكة اختبار Solana المجانية)، تحصل على إسقاطات SOL مجانًا.

توجد مزايا السرعة بسبب القرارات المعمارية التي تجعل تطوير Solana أصعب من تطوير Ethereum على المستوى الخام. Anchor تعالج هذه الأجزاء الصعبة بالضبط.

كيف تخزن Solana البرامج والبيانات

على Solana، "الحسابات" ليست حسابات مستخدمين أو حسابات محافظ بالمعنى اليومي. الحسابات هي وحدات تخزين على البلوكتشين: حاويات مميزة يمكنها الاحتفاظ بالبيانات، أو رصيد SOL، أو كود برنامج قابل للتنفيذ.

التمييز المعماري الأساسي: على Solana، تعيش البرامج (الكود القابل للتنفيذ) والبيانات (الحالة) في حسابات منفصلة. البرامج عديمة الحالة. يحتوي حساب البرنامج فقط على البايت كود المترجم. تعيش البيانات في حسابات بيانات منفصلة يقرأ منها ويكتب إليها البرنامج.

في Ethereum، العقد الذكي يشبه شقة مكتفية ذاتيًا: الكود والأثاث يعيشان في نفس المساحة. في Solana، البرنامج يشبه شركة بها أقسام منفصلة: المنطق القابل للتنفيذ يعيش في حساب واحد، والبيانات التي يقرأها ويكتبها تعيش في حسابات أخرى تمامًا.

السمةالعقد الذكي Ethereumبرنامج Solana + الحساب
تخزين الكودداخل العقدحساب برنامج منفصل
تخزين الحالةداخل العقدحساب (أو حسابات) بيانات منفصلة
المطور يدير الحسابات؟لانعم (يقوم Anchor بأتمتة ذلك)
اللغةSolidityRust (عبر Anchor)
ذات حالة (Stateful)؟نعمالبرامج عديمة الحالة؛ الحالة موجودة في الحسابات

لكل حساب Solana ثلاث خصائص: مالك (برنامج يتحكم فيه)، وعنوان مفتاح عمومي (معرفه داخل الكتلة)، ورصيد lamport (أصغر وحدة في SOL، حيث يساوي 1 SOL مليار lamports). تحتوي حسابات البيانات أيضاً على بيانات برمجية متسلسلة.

النتيجة العملية: عندما تستدعي برنامج Solana، يجب عليك تمرير كل حساب سيقوم البرنامج بقراءته أو الكتابة فيه بشكل صريح. يجب عليك إثبات الملكية. يجب عليك التصريح عن الحسابات القابلة للتغيير. يجب عليك التحقق من الحسابات التي تعد جهات توقيع. في Rust الخام، تتطلب إدارة الحسابات هذه مئات السطور من أكواد التحقق لكل برنامج.

هذه الإدارة الصريحة للحسابات هي بالضبط المشكلة التي صُمم نظام قيود Anchor لحلها.


المكونات الأساسية لإطار عمل Solana Anchor: IDL، والماكرو، وPDAs، وCPI

يوفر Anchor أربع آليات مترابطة تقضي معاً على معظم التعقيدات في تطوير Solana الخام. فهم كل منها بالتسلسل هو شرط مسبق لكتابة برنامجك الأول.

لغة تعريف الواجهة (IDL): عقد اتصال Anchor

يقوم Anchor تلقائياً بإنشاء ملف JSON يسمى لغة تعريف الواجهة (IDL) كلما قمت بتشغيل anchor build. فكر فيه كمواصفات OpenAPI لبرنامجك داخل الكتلة: وصف مقروء آلياً لكل تعليمة يقبلها برنامجك، وكل حساب تتطلبه تلك التعليمات، وكل نوع بيانات متضمن.

تمثل IDL لـ Anchor ما تمثله ABI (واجهة تطبيق ثنائية) لعقد Solidity على Ethereum. إذا قمت بالبناء على Ethereum، فأنت تعرف بالفعل كيف تتيح ملفات ABI لأكواد الواجهة الأمامية استدعاء وظائف العقد مع سلامة الأنواع. تقوم IDL الخاصة بـ Anchor بنفس الشيء لبرامج Solana، ويتم إنشاؤها تلقائياً من كود Rust الخاص بك. لا تكتبها يدوياً أبداً.

يستقر ملف IDL في target/idl/your_program_name.json بعد anchor build. وإلى جانبه، يقوم Anchor بإنشاء target/types/your_program_name.ts؛ وهو ملف من نوع TypeScript تستورده نصوص الواجهة الأمامية أو الاختبار للحصول على وصول مكتوب بالكامل لتعليمات برنامجك.

يبدو ملف IDL المختصر كما يلي:

{
  "version": "0.1.0",
  "name": "balance_tracker",
  "instructions": [
    {
      "name": "initialize",
      "accounts": [
        { "name": "balanceAccount", "isMut": true, "isSigner": false },
        { "name": "user",           "isMut": true, "isSigner": true  },
        { "name": "systemProgram",  "isMut": false, "isSigner": false }
      ],
      "args": []
    },
    {
      "name": "deposit",
      "accounts": [
        { "name": "balanceAccount", "isMut": true, "isSigner": false },
        { "name": "user",           "isMut": false, "isSigner": true }
      ],
      "args": [{ "name": "amount", "type": "u64" }]
    }
  ]
}

يقرأ عميل TypeScript ملف IDL هذا ويمنحك استدعاءات دوال مكتوبة بالكامل (program.methods.initialize() و program.methods.deposit(amount)) دون أي كتابة يدوية للواجهة. مهارات TypeScript الخاصة بك قابلة للتطبيق مباشرة هنا.

ماكرو Anchor: كيف يقضي Anchor على الأكواد المتكررة

يوفر Anchor مجموعة من ماكرو Rust، وهي مولدات أكواد تكتب منطق التحقق المتكرر نيابة عنك. الماكرو في Rust هو تعليق توضيحي يتوسع إلى كود في وقت التجميع. تنشئ ماكرو Anchor أكواد التحقق من الحساب، والتسلسل، ومعالجة الأخطاء التي كنت ستكتبها يدوياً لولا ذلك.

تشكل ثلاثة ماكرو جوهر كل برنامج Anchor:

#[program] يميز الوحدة التي تحتوي على وظائف معالجة التعليمات الخاصة بك. يعامل Anchor كل وظيفة عامة في هذه الوحدة كتعليمات قابلة للاستدعاء.

#[derive(Accounts)] ينشئ كود التحقق من الحساب من تعريف هيكل Rust. أنت تصرح بالحسابات التي تحتاجها التعليمات، ويقوم Anchor بإنشاء الكود للتحقق من الملكية والقابلية للتغيير، بالإضافة إلى نوع كل حساب، تلقائياً.

#[account] يميز الهيكل كنوع بيانات حساب مدار بواسطة Anchor ويضيف مميز الـ 8 بايت الذي يتيح لـ Anchor تمييز نوع حسابك عن الأنواع الأخرى.

إليك كيف تبدو هذه الماكرو في السياق:

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,           // يقوم Anchor بإنشاء هذا الحساب (ويتحقق من عدم وجوده)
        payer = user,   // حساب الـ 'user' يمول إيداع الإعفاء من الإيجار
        space = 8 + 8   // مميز 8 بايت + 8 بايت لحقل الإجمالي u64
    )]
    pub balance_account: Account<'info, BalanceAccount>,

    #[account(mut)]          // يصرح بأن الرصيد (lamport) لهذا الحساب سيتغير
    pub user: Signer<'info>, // نوع Signer: يتحقق Anchor من أن هذا الحساب وقع المعاملة

    pub system_program: Program<'info, System>,
}

قيود الحساب: كيف يتحقق Anchor من الحسابات تلقائياً

كل سمة داخل #[account(...)] هي قيد من قيود Anchor. القيود هي قواعد تحقق تعمل تلقائياً قبل تنفيذ منطق التعليمات الخاص بك. وهي السبب الرئيسي وراء تطلب برامج Anchor كود تحقق يدوي أقل بكثير من برامج Rust الخام.

القيود الأكثر شيوعاً هي:

#[derive(Accounts)]
pub struct ExampleAccounts<'info> {
    #[account(init, payer = user, space = 8 + 8)]
    // init: ينشئ الحساب؛ يتراجع إذا كان موجوداً بالفعل
    pub new_account: Account<'info, MyData>,

    #[account(mut)]
    // mut: يصرح بأن بيانات هذا الحساب أو رصيد الـ lamport سيتغير
    pub existing_account: Account<'info, MyData>,

    #[account(seeds = [b"vault", user.key().as_ref()], bump)]
    // seeds + bump: يشتق عنوان PDA ويتحقق من الـ bump المتعارف عليه
    pub pda_account: Account<'info, VaultData>,

    #[account(constraint = user_account.authority == user.key())]
    // constraint: يقيم تعبيراً منطقياً؛ ويفشل إذا كان خطأ
    pub user_account: Account<'info, UserData>,

    pub user: Signer<'info>,
    // Signer: يتحقق من أن الحساب وقع المعاملة
}

بدون القيود، كنت ستكتب كل من هذه الفحوصات يدوياً في جسم التعليمات الخاص بك. مع القيود، يفرضها Anchor قبل تشغيل منطق التعليمات. يعد هذا مكسباً للإنتاجية وميزة أمنية في نفس الوقت، لأن نسيان القيود أصعب من نسيان الفحوصات اليدوية المدفونة في كود التعليمات.

عناوين البرامج المشتقة (PDAs): التخزين الحتمي داخل الكتلة

يعد عنوان البرنامج المشتق (PDA) أحد أصعب المفاهيم في تطوير Solana. خطط لقراءة هذا القسم مرتين. تفتح PDAs أحد أقوى الأنماط في Solana، ويجعلها Anchor أكثر سهولة في الإدارة بكثير من Rust الخام.

عنوان الـ PDA هو عنوان حساب مشتق حتمياً من مجموعة من البذور (seeds) ومعرف البرنامج. على عكس عنوان المحفظة العادي، لا يحتوي PDA على مفتاح سري مطابق. لا يمكن لأي مستخدم فردي التوقيع نيابة عن PDA. فقط البرنامج المالك يمكنه تفويض المعاملات المتعلقة به.

فكر في PDA كصندوق أمانات لا يمكن إلا للبنك (البرنامج) فتحه. لا يملك أي عميل المفتاح؛ البنك يتحكم في الوصول برمجياً. وهذا يجعل PDAs مثالية للخزائن التي يتحكم فيها البرنامج، وحسابات الضمان، والتخزين الخاص بالمستخدم حيث يجب أن تكون السلطة للبرنامج، وليس للمستخدم.

في Rust الخام، يتطلب اشتقاق PDA استدعاء Pubkey::find_program_address(&seeds, &program_id) والتحقق يدوياً من النتيجة. يتعامل Anchor مع هذا باستخدام قيد seeds:

#[derive(Accounts)]
pub struct CreateVault<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + 32,
        seeds = [b"vault", authority.key().as_ref()], // البذور تحدد عنوان الـ PDA
        bump                 // يجد Anchor ويخزن بذرة الـ bump المتعارف عليها
    )]
    pub vault: Account<'info, Vault>,   // حساب PDA، لا يوجد مفتاح سري

    #[account(mut)]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,
}

يحدد القيد seeds لـ Anchor كيفية اشتقاق عنوان PDA. يخزن الحقل bump بذرة الـ bump القانونية، وهي عدد صحيح صغير يضمن أن العنوان المشتق يقع خارج المنحنى الإهليلجي ولا يمتلك مفتاح سري. في إصدار Anchor v0.29.x، يتم اشتقاق الـ bump القانوني والتحقق منه تلقائياً.

عناوين PDA حتمية: بمعطيات نفس البذور ومعرف البرنامج، فإنها تنتج دائماً نفس العنوان. تتيح هذه الخاصية للعملاء حساب عنوان PDA خارج الكتلة لجلب البيانات، بينما يتحكم البرنامج في صلاحيات الكتابة.

استدعاء البرامج المتقاطع (CPI): كيف تتواصل البرامج مع بعضها البعض

استدعاء البرامج المتقاطع (CPI) هو آلية سولانا التي تسمح لبرنامج ما باستدعاء تعليمات برنامج آخر. إنه المعادل داخل الكتلة لاستدعاء وظيفة مكتبة مشتركة. يتيح CPI قابلية التكوين: يمكن لبروتوكول DeFi الخاص بك استدعاء برنامج SPL Token لنقل الرموز، ويمكن لعقد الحوكمة الخاص بك استدعاء برنامج التخزين (staking)، وهكذا.

مكتبة برنامج سولانا (SPL) هي معادل سولانا للمكتبة القياسية للبرامج داخل الكتلة. برنامج SPL Token لسولانا هو بمثابة ERC-20 لإيثيريوم، ولكنه مطبق كبرنامج مشترك داخل الكتلة بدلاً من قالب عقد يقوم كل مشروع بنشره بشكل مستقل. عندما يحتاج برنامج Anchor الخاص بك إلى سك أو تحويل الرموز، فإنه يستدعي SPL Token عبر CPI.

يسهل Anchor استدعاءات CPI باستخدام حزمة anchor-spl و CpiContext:

use anchor_spl::token::{self, Transfer, Token};

pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
    let cpi_accounts = Transfer {
        from: ctx.accounts.vault_token_account.to_account_info(), // حساب رمز المصدر
        to: ctx.accounts.user_token_account.to_account_info(),   // حساب رمز الوجهة
        authority: ctx.accounts.vault.to_account_info(),         // توقيع PDA للخزينة
    };
    let cpi_ctx = CpiContext::new(ctx.accounts.token_program.to_account_info(), cpi_accounts);
    token::transfer(cpi_ctx, amount)?;  // يستدعي تعليمات التحويل الخاصة بـ SPL Token
    Ok(())
}

بدون Anchor، يتطلب تجميع معلومات الحسابات، وبناء التعليمات، واستدعاء invoke_signed حوالي 30 سطراً. تقلل أدوات المساعدة في CPI الخاصة بـ Anchor هذا إلى استدعاء وظيفة مكتوبة بوضوح وقابلة للقراءة.

سوف تضع هذه المفاهيم موضع التنفيذ في البرنامج التعليمي خطوة بخطوة.


المتطلبات المسبقة: ما تحتاجه قبل تثبيت إطار عمل Anchor

هناك أربع أدوات مطلوبة قبل أن تتمكن من البناء باستخدام إطار عمل Anchor على سولانا.

الأدوات المطلوبة:

  1. Rust و Cargo (عبر rustup)، يوصى بالإصدار 1.70.0 أو أحدث
  2. Solana CLI (v1.18.x أو أحدث)، وهي أداة سطر الأوامر الرسمية للتفاعل مع شبكة سولانا؛ وتتعامل مع إدارة المحفظة، وطلبات الإيردروب، وتكوين المجموعات (clusters)
  3. Node.js (v18 أو أحدث) بالإضافة إلى Yarn أو npm، وهي مطلوبة لعميل TypeScript واختبارات Anchor
  4. Anchor Version Manager (avm)، الذي يقوم بتثبيت وإدارة إصدارات Anchor CLI؛ قم دائماً بتثبيت Anchor عبر avm بدلاً من تثبيته مباشرة عبر Cargo

بخصوص Rust: تتم كتابة برامج Anchor بلغة Rust. لغة Rust مطلوبة، ولا يوجد مسار بديل لذلك. ومع ذلك، تقوم وحدات الماكرو في Anchor بتجريد أصعب أنماط Rust: التحقق من صحة الحسابات والتسلسل، بالإضافة إلى انتشار الأخطاء. لا تحتاج إلى إتقان عميق للغة Rust لبناء برنامجك الأول.

ما تحتاجه للبدء: الهياكل (structs)، والوظائف (functions)، والملكية الأساسية (basic ownership)، وسمات القيود (trait bounds) على مستوى سطحي. ما يمكنك تأجيله لوقت لاحق: فترات الحياة (lifetimes)، و Rust غير المتزامن (async Rust)، والنقاط الدقيقة في مدقق الاستعارة (borrow checker). تنطبق مهارات TypeScript أو JavaScript الخاصة بك مباشرة على كود جانب العميل في Anchor. تستخدم الاختبارات، وتفاعلات الواجهة الأمامية، واستدعاءات العميل التي تم إنشاؤها بواسطة IDL لغة TypeScript. لست بحاجة إلى أن تكون خبيراً في Rust للبناء باستخدام Anchor، تماماً كما لا تحتاج إلى أن تكون خبيراً في Ruby للبناء باستخدام Ruby on Rails. ولكنك ستواجه Rust، والإلمام الأساسي بها سيساعدك.

إذا كان تجريد Anchor لأنماط Rust يثير اهتمامك، فإن قسم المكونات الأساسية يشرح ما يجرده Anchor من Rust بالتفصيل.

حول واجهة Solana CLI مقابل واجهة Anchor CLI: هاتان أداتان منفصلتان بمسؤوليات مختلفة. تتعامل واجهة solana CLI مع التفاعل مع الشبكة: التحقق من الرصيد، وطلب الإيردروب، والتبديل بين devnet و مينيت. تتعامل واجهة anchor CLI مع دورة حياة برنامجك: تهيئة المشاريع، وبناء البرامج، وإجراء الاختبارات، والنشر. كلاهما مطلوب.


كيفية تثبيت إطار عمل Anchor: إعداد خطوة بخطوة

📌 ملاحظة: تم التحقق من جميع الأوامر أدناه لنسخة Anchor v0.29.x و Solana CLI v1.18.x اعتباراً من عام 2024. قم بتشغيل anchor --version بعد التثبيت لتأكيد إصدارك. إذا كنت تقرأ هذا بعد النشر، فتحقق من الإصدار الحالي في مستودع Anchor على GitHub (coral-xyz/anchor).

الخطوة 1: تثبيت Rust عبر rustup

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# اتبع التعليمات التي تظهر على الشاشة وحدد التثبيت الافتراضي
source "$HOME/.cargo/env"
rustc --version
# يجب أن يطبع: rustc 1.70.0 أو أحدث

الخطوة 2: تثبيت Solana CLI

sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
# اتبع تعليمات PATH من مخرجات المثبت
solana --version
# يجب أن يطبع: solana-cli 1.18.x أو أحدث

عندما تقوم بنشر برنامج Anchor على سولانا، يتم تخزينه داخل الكتلة ويتم تنفيذه بواسطة عُقد التحقق في الشبكة كلما استدعته إحدى المعاملات. واجهة Solana CLI هي الطريقة التي تتفاعل بها مع أدوات التحقق هذه من جهازك.

الخطوة 3: تكوين Solana CLI على devnet وإنشاء محفظة

solana config set --url devnet
solana-keygen new
# ينشئ ملف زوج مفاتيح محلي (محفظة التطوير الخاصة بك)
# احفظ مسار الإخراج. يستخدم Anchor زوج المفاتيح هذا لتوقيع عمليات النشر

💡 نصيحة: احفظ مسار ملف زوج المفاتيح الخاص بك. يقرأ Anchor زوج المفاتيح هذا من ملف التكوين Anchor.toml الخاص بك لتوقيع معاملات النشر على devnet.

الخطوة 4: اطلب إيردروب لعملة SOL على devnet

solana airdrop 2
solana balance
# تأكد من أن الرصيد يظهر 2 SOL

الخطوة 5: تثبيت avm (Anchor Version Manager) و Anchor

cargo install --git https://github.com/coral-xyz/avm avm --locked --force
avm install latest
avm use latest
anchor --version
# يجب أن يطبع: anchor-cli 0.29.x

📌 ملاحظة: قم دائماً بتثبيت Anchor من خلال avm بدلاً من تثبيته مباشرة عبر cargo install anchor-cli. يتيح لك avm التبديل بين إصدارات Anchor دون إعادة التثبيت. هذا الأمر مهم عندما ترتبط المشاريع بإصدار معين أو عندما تقوم بترقية مشروع موجود.

الخطوة 6: ابدأ مشروعك الأول

anchor init my-first-program
cd my-first-program

هيكل مشروعك بعد anchor init:

my-first-program/
├── Anchor.toml
├── programs/
│   └── my-first-program/
│       └── src/
│           └── lib.rs
├── tests/
│   └── my-first-program.ts
└── app/

💡 نصيحة: يقوم الأمر anchor init بإنشاء نموذج برنامج تجريبي يعمل في lib.rs. قم بتشغيل anchor test فوراً للتأكد من أن بيئتك تعمل قبل كتابة أي كود خاص بك.


بناء ونشر أول برنامج Anchor لك: شرح كامل**

يأخذك هذا القسم من مشروع فارغ إلى برنامج منشور على شبكة devnet الخاصة بسولانا. المثال هو متتبع الرصيد: برنامج يقوم بتهيئة الرصيد المخزن إلى الصفر ثم يقبل تعليمات الإيداع لزيادته. يوضح هذا دورة حياة الحساب الكاملة وهو مطابق وظيفياً لبرنامج العداد ولكنه يستخدم أسماء متغيرات أصلية.

كتابة برنامج متتبع الرصيد

يحتوي ملف programs/my-first-program/src/lib.rs الخاص بك بالفعل على كود أساسي من anchor init. استبدل محتوياته بما يلي:

// برنامج متتبع الرصيد Anchor v0.29.x
use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkgHH5WfZCnQ");

#[program]
pub mod balance_tracker {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        ctx.accounts.balance_account.total = 0;  // الرصيد الابتدائي هو صفر
        Ok(())
    }

    pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {
        ctx.accounts.balance_account.total += amount;  // زيادة الرصيد المخزن
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = user,
        space = 8 + 8   // 8-byte Anchor discriminator + 8 bytes for u64
    )]
    pub balance_account: Account<'info, BalanceAccount>,

    #[account(mut)]
    pub user: Signer<'info>,

    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Deposit<'info> {
    #[account(mut)]
    pub balance_account: Account<'info, BalanceAccount>,
    pub user: Signer<'info>,
}

#[account]
pub struct BalanceAccount {
    pub total: u64,
}

هناك ثلاثة أنماط في هذا الكود تهمنا قبل المتابعة. أولاً، يقوم #[derive(Accounts)] بإنشاء منطق التحقق من الحساب بالكامل. يقرأ Anchor تعريف الهيكل (struct) الخاص بك ويكتب عمليات التحقق من الملكية، وعمليات التحقق من القابلية للتغيير، والتحقق من الموقع (Signer). أنت تعلن عن النية، وAnchor يفرضها. ثانيًا، يقوم space = 8 + 8 بتخصيص البايتات التي يحتاجها الحساب بالضبط: 8 بايت لمميز Anchor (علامة فريدة تحدد نوع الحساب وتمنع هجمات الخلط بين الحسابات) بالإضافة إلى 8 بايت لإجمالي u64. ثالثاً، Signer<'info> هو النوع المدمج في Anchor الذي يتحقق من أن الحساب قد وقع على المعاملة. بدونه، يمكن لأي حساب استدعاء تعليمات الإيداع الخاصة بك.

اختبار برنامجك باستخدام Mocha و TypeScript

Mocha هو مشغل اختبار JavaScript؛ وChai يوفر صيغة التأكيد (assertion). كلاهما مثبت مسبقًا عند تشغيل anchor init. افتح tests/my-first-program.ts واستبدل محتوياته بـ:

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyFirstProgram } from "../target/types/my_first_program";
import { assert } from "chai";

describe("balance-tracker", () => {
  const provider = anchor.AnchorProvider.env();
  anchor.setProvider(provider);

  const program = anchor.workspace.MyFirstProgram as Program<MyFirstProgram>;
  const balanceAccount = anchor.web3.Keypair.generate();

  it("Initializes a balance account with total = 0", async () => {
    await program.methods
      .initialize()
      .accounts({
        balanceAccount: balanceAccount.publicKey,
        user: provider.wallet.publicKey,
        systemProgram: anchor.web3.SystemProgram.programId,
      })
      .signers([balanceAccount])
      .rpc();

    const account = await program.account.balanceAccount.fetch(
      balanceAccount.publicKey
    );
    assert.equal(account.total.toNumber(), 0, "Initial balance should be 0");
  });

  it("Deposits 500 and updates the stored balance", async () => {
    await program.methods
      .deposit(new anchor.BN(500))
      .accounts({
        balanceAccount: balanceAccount.publicKey,
        user: provider.wallet.publicKey,
      })
      .rpc();

    const account = await program.account.balanceAccount.fetch(
      balanceAccount.publicKey
    );
    assert.equal(account.total.toNumber(), 500, "Balance should be 500 after deposit");
  });
});

حزمة npm المسماة @coral-xyz/anchor هي مكتبة عميل TypeScript الخاصة بـ Anchor. تم إنشاء نوع Program<MyFirstProgram> تلقائيًا من IDL عند تشغيل anchor build. هذه هي القيمة العملية لـ IDL في الواقع: يحصل كود TypeScript الخاص بك على أمان كامل للأنواع (type safety) عبر واجهة برنامج Rust الخاص بك دون الحاجة إلى كتابة أي واجهة يدويًا.

هذا البرنامج هو أيضًا الواجهة الخلفية لتطبيق لامركزي (dApp). عميل TypeScript الموضح أعلاه هو الكيفية التي سيستدعيه بها تطبيق الواجهة الأمامية. أضف واجهة مستخدم React أو Next.js فوق استدعاءات الأساليب (methods) هذه وستحصل على تطبيق لامركزي كامل يعمل على Solana.

البناء والنشر على Devnet

قم بتشغيل هذه الأوامر الثلاثة بالتسلسل من جذر مشروعك:

anchor build
# المخرجات: target/deploy/my_first_program.so, target/idl/my_first_program.json, target/types/my_first_program.ts
anchor test
# يبدأ المدقق المحلي، وينشر البرنامج، ويشغل اختبارات Mocha، ثم يتوقف
anchor deploy --provider.cluster devnet
# المخرجات تشمل معرف البرنامج الخاص بك: ABC123...xyz789

💡 نصيحة: قم بنسخ معرف البرنامج (Program ID) من مخرجات النشر. قم بتحديث قيمة declare_id!("...") في ملف lib.rs به، ثم قم بتشغيل anchor build مرة أخرى لدمج العنوان الصحيح في برنامجك المجمع. قم أيضًا بتحديث قسم [programs.devnet] في ملف Anchor.toml.

📌 ملاحظة: أنت تقوم بالنشر على devnet، وهي شبكة اختبار Solana. لا يكلف هذا أي عملات SOL حقيقية. يغطي إيردروب devnet الخاص بك من قسم الإعداد رسوم النشر.

لقد قمت الآن بكتابة واختبار برنامج Solana، ثم نشرته باستخدام إطار عمل Anchor. البرنامج موجود الآن على devnet عند معرف البرنامج الخاص بك وينفذ كلما استدعته معاملة.


اختبار برامج Anchor: سير عمل anchor test

anchor test هو أمر واحد يبدأ مدقق Solana محلي، وينشر برنامجك عليه، ويشغل مجموعة اختبارات Mocha الكاملة، ويغلق المدقق عند الانتهاء. لست بحاجة إلى إدارة المدقق يدويًا.

سلسلة سير عمل الاختبار:

  1. يقرأ anchor test ملف Anchor.toml الخاص بك للإعدادات
  2. يبدأ عملية مدقق محلي في الخلفية
  3. يبني وينشر برنامجك على ذلك المدقق
  4. يشغل جميع ملفات اختبار TypeScript في دليل tests/ الخاص بك باستخدام Mocha
  5. يطبع نتائج النجاح/الفشل ويغلق المدقق

هيكل ملف الاختبار: يستورد كل ملف اختبار من @coral-xyz/anchor ويقوم بإعداد موفر (يتصل بالمدقق المحلي)، ويشير إلى برنامجك من خلال كائن مساحة العمل الناتج عن IDL. كتل describe و it هي صيغ Mocha القياسية.

جلب بيانات الحساب: بعد استدعاء إحدى التعليمات، قم بجلب الحساب داخل الكتلة للتأكد من حالته:

const account = await program.account.balanceAccount.fetch(
  balanceAccount.publicKey
);
assert.equal(account.total.toNumber(), 0);

اختبار حالات الخطأ: اختبر أن المدخلات غير الصالحة تفشل بشكل صحيح. يتضمن البرنامج المختبر جيدًا اختبارات سلبية:

it("Rejects deposit from an unsigned account", async () => {
  const badActor = anchor.web3.Keypair.generate();
  try {
    await program.methods
      .deposit(new anchor.BN(100))
      .accounts({
        balanceAccount: balanceAccount.publicKey,
        user: badActor.publicKey,
      })
      .rpc();
    assert.fail("Transaction should have been rejected");
  } catch (err) {
    assert.ok(err, "Anchor rejected the unsigned transaction");
  }
});

الشبكة المحلية (Localnet) مقابل devnet: استخدم anchor test (الشبكة المحلية) لجميع عمليات التطوير النشطة. الشبكة المحلية فورية ومجانية، وتتم إعادة ضبطها بين عمليات التشغيل. لا تنشر على devnet إلا عندما تريد مشاركة رابط دائم أو الاختبار مقابل ظروف الشبكة الفعلية.

Mocha هو مشغل الاختبار (هيكل كتل describe و it). يوفر Chai صيغة التأكيد (assert.equal و assert.ok و expect). كلاهما مسبق الإعداد في كل مشروع anchor init ولا يتطلبان تثبيتًا منفصلاً.


Anchor مقابل البدائل: اختيار مسار تطوير Solana الخاص بك

توجد ثلاثة مسارات تطوير للبناء على Solana: إطار عمل Anchor، و Rust الأصلي بدون إطار عمل، و Seahorse. تعد Solana نفسها واحدة من عدة سلاسل كتل تستحق التقييم لمشروعك. تقدم الجداول أدناه الاختلافات الرئيسية دون تحيز.

الجدول 1: نهج تطوير Solana

AnchorNative Rust (بدون إطار عمل)Seahorse
اللغةRust + عميل TypeScriptRust فقطPython (تُترجم إلى Rust)
الأكواد المتكررة المطلوبةمنخفضة (الماكرو يعالج التحقق)عالية (أكواد تحقق يدوية)منخفضة
نضج الإنتاججاهز للإنتاججاهز للإنتاجتجريبي
حجم المجتمعكبير (المعيار الفعلي)متوسطصغير
منحنى التعلممتوسط (يتطلب أساسيات Rust)شديد الصعوبة (يتطلب Rust بالكامل)منخفض (بناء جملة Python)
توليد IDL/العميلتلقائييدويعبر Anchor (خلف الكواليس)
الأفضل لـمعظم عمليات تطوير تطبيقات Solanaالبرامج على مستوى النظام التي تحتاج إلى تحكم كاملمطوري Python للنماذج الأولية

الجدول 2: أدوات Solana مقابل Ethereum

Anchor (Solana)Hardhat (Ethereum)Foundry (Ethereum)
البلوكتشينSolanaEthereumEthereum
اللغة الأساسيةRustSolidity + JavaScriptSolidity
لغة الاختبارTypeScript (Mocha)JavaScript/TypeScriptSolidity (أصلية)
نموذج البرنامجبرامج عديمة الحالة + حسابات منفصلةعقود ذات حالةعقود ذات حالة
الإنتاجية~65,000 TPS (مثالية، اعتبارًا من 2024)~15–30 TPS (مينيت، اعتبارًا من 2024)~15–30 TPS (مينيت، اعتبارًا من 2024)
رسوم المعاملاتعادةً أقل من $0.001متغيرة (غالبًا $1–50+ لكل معاملة)متغيرة (غالبًا $1–50+ لكل معاملة)
نضج المنظومةمتنامية؛ أحدث سناًأكبر منظومة عقود ذكيةأكبر منظومة عقود ذكية
مجموعة تدقيق الأمانأصغر، متناميةأكبر، راسخةأكبر، راسخة
الأفضل لـالتطبيقات عالية التردد والرسوم المنخفضةالمنظومة الأوسع؛ أقصى سجل أمانمستخدمي Ethereum المحترفين الذين يفضلون الاختبار الأصلي بـ Solidity

متى تختار Anchor بدلاً من Rust الأصلي: بالنسبة للعديد من حالات استخدام تطوير تطبيقات Solana، بما في ذلك بروتوكولات DeFi، ومنصات NFT، وأنظمة حظر التوكنات، والمنظمات اللامركزية المستقلة (DAOs)، والألعاب داخل الكتلة، يعد Anchor نقطة بداية شائعة. تقليل الأكواد المتكررة كبير: فالبرنامج الذي يتطلب 300 سطر في Rust الخام قد يستغرق 80 سطراً مع Anchor. يكون تطوير Rust الأصلي منطقيًا عندما يتطلب البرنامج تحكمًا دقيقًا في استهلاك وحدات الحوسبة، أو عندما تتعارض تجريدات Anchor مع بنية غير عادية، أو عندما يمتلك الفريق خبرة عميقة في Rust ويحتاج إلى أقصى قدر من المرونة.

إطار عمل Seahorse: يسمح Seahorse للمطورين بكتابة برامج Solana بلغة Python، والتي يقوم Seahorse بعد ذلك بترجمتها إلى Rust متوافق مع Anchor خلف الكواليس. وهذا يقلل من حاجز اللغة لمطوري Python الذين يرغبون في تجربة Solana دون تعلم Rust. والمقايضة هنا هي النضج: Seahorse هو مشروع مجتمعي بقاعدة مستخدمين أصغر بكثير من Anchor ولا يُنصح به لتطبيقات الإنتاج اعتبارًا من عام 2024. بالنسبة للنماذج الأولية، فهو خيار معقول؛ أما بالنسبة للإنتاج، فيظل Anchor هو المعيار الفعلي.

Ethereum مقابل Solana: توفر Ethereum أكبر منظومة لمطوري العقود الذكية، وأعمق تاريخ لتدقيق الأمان، وأوسع دعم للأدوات. توفر Solana إنتاجية أعلى بكثير ورسومًا أقل، مما يجعلها أكثر ملاءمة للتطبيقات التي تكون فيها وتيرة المعاملات وتكلفتها هي القيود الأساسية. وتناسب هذه المنصات ملفات تعريف التطبيقات المختلفة. قد يفضل المطورون الذين يبنون بنية تحتية للتداول عالي التردد أو ألعاب المعاملات الدقيقة Solana؛ بينما قد يفضل المطورون الذين يبنون أنظمة حوكمة أو معايير توكنات تحتاج إلى أقصى قدر من التوافق مع المنظومة Ethereum. بالنسبة لمعظم تطبيقات Solana الإنتاجية، يعد Anchor نقطة بداية شائعة، وهو ما أكدته البروتوكولات الكبرى بما في ذلك Raydium وMarinade Finance وMetaplex باختيار Anchor كأساس لها.


أمان إطار عمل Anchor: خمس ثغرات أمنية يجب على كل مطور Solana معرفتها

⚠️ تحذير: الثغرات الأمنية في برامج Solana يمكن أن تؤدي إلى خسارة دائمة وغير قابلة للاسترداد لأموال المستخدمين. قبل نشر أي برنامج في المينيت، قم بتشغيله من خلال أداة تحليل سكوني مثل Soteria وفكر في إجراء تدقيق أمني احترافي. شهدت منظومة Solana عمليات استغلال كبيرة من الثغرات الأمنية الموضحة أدناه بالضبط. مراجعة الأمان ليست اختيارية لبرامج الإنتاج. لمزيد من القراءة العميقة، راجع توثيق Anchor الرسمي.

نظام القيود في Anchor، أي سمات #[account(...)] في هياكل حساباتك، هو خط الدفاع الأمني الأول لديك. فهو يفرض تلقائيًا عمليات التحقق من الملكية، وأذونات القابلية للتغيير، والتحقق من النوع الذي كنت ستكتبه يدويًا في Rust الخام. لكن القيود تحمي فقط ما تعلن عنه. تنشأ الثغرات الأمنية أدناه مما ينسى المطورون التصريح عنه.

فقدان التحقق من الموقّع (Missing Signer Check)

يمكن لأي حساب استدعاء تعليماتك إذا لم يكن المتصل مطلوبًا منه التوقيع على المعاملة. وهذا يسمح لأي محفظة باستدعاء التعليمات التي يجب أن تكون مقيدة.

// ثغرة: لا يتحقق AccountInfo مما إذا كان المتصل قد وقع على المعاملة
#[derive(Accounts)]
pub struct Deposit<'info> {
    #[account(mut)]
    pub balance_account: Account<'info, BalanceAccount>,
    pub user: AccountInfo<'info>,  // لا يوجد تحقق من التوقيع
}
// آمن: تفشل Signer<'info> المعاملة إذا لم يوقع الحساب
#[derive(Accounts)]
pub struct Deposit<'info> {
    #[account(mut)]
    pub balance_account: Account<'info, BalanceAccount>,
    pub user: Signer<'info>,  // تتراجع المعاملة إذا لم يوقع المستخدم
}

استخدم Signer<'info> لأي حساب يجب أن يصرح بتعليمات.

فقدان التحقق من الملكية (استبدال الحساب)

يمكن للمهاجم استبدال حساب مصمم بشكل ضار له نفس تخطيط البيانات مثل حسابك المتوقع ولكنه مملوك لبرنامج مختلف.

// ثغرة: لا يتحقق AccountInfo من مالك البرنامج للحساب
pub balance_account: AccountInfo<'info>,  // يقبل أي حساب
// آمن: يتحقق Account<'info, T> من أن الحساب مملوك لبرنامجك
pub balance_account: Account<'info, BalanceAccount>,  // التحقق من الملكية تلقائي

استخدم دائمًا غلاف Anchor المكتوب Account<'info, T> بدلاً من AccountInfo<'info> الخام للحسابات التي تحتوي على بيانات يتحكم فيها البرنامج.

هجوم إعادة التهيئة (Reinitialization Attack)

إذا كان من الممكن تشغيل تعليمة initialize أكثر من مرة على نفس الحساب، فيمكن للمهاجم إعادة ضبط الحالة التي يجب أن تكون دائمة.

// ثغرة: تقبل init_if_needed الحسابات التي تمت تهيئتها بالفعل بصمت
#[account(init_if_needed, payer = user, space = 8 + 8)]
pub balance_account: Account<'info, BalanceAccount>,
// آمن: تتراجع init إذا كان الحساب موجوداً بالفعل
#[account(init, payer = user, space = 8 + 8)]
pub balance_account: Account<'info, BalanceAccount>,

استخدم init (وليس init_if_needed) للحسابات التي يجب إنشاؤها مرة واحدة فقط. إذا كانت init_if_needed ضرورية حقًا، فأضف علامة تهيئة صريحة وتحقق منها في منطق التعليمات الخاص بك.

تجاوز الحد الأعلى والأسفل للأعداد الصحيحة (Integer Overflow and Underflow)

تتعطل العمليات الحسابية في Rust عند التجاوز في إصدارات التصحيح (debug builds) ولكنها تلتف بصمت في إصدارات الإصدار (release builds)، مما قد يؤدي إلى إتلاف أرصدة مالية دون ظهور خطأ.

// ثغرة: العمليات الحسابية المباشرة تلتف بصمت في وضع الإصدار
pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {
    ctx.accounts.balance_account.total += amount;
    Ok(())
}
// آمن: تعيد checked_add خطأ Err بدلاً من الالتفاف عند التجاوز
pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {
    ctx.accounts.balance_account.total = ctx.accounts.balance_account.total
        .checked_add(amount)
        .ok_or(error!(ErrorCode::Overflow))?;
    Ok(())
}

استخدم checked_add و checked_sub و checked_mul لجميع العمليات الحسابية على القيم المالية. حدد تعداد ErrorCode مخصصًا مع متغير Overflow لرسائل خطأ واضحة.

توحيد الـ PDA Bump (PDA Bump Canonicalization)

يمكن أن يؤدي استخدام بذرة bump غير معيارية إلى إنتاج عنوان PDA صالح ولكنه غير متوقع، مما يتيح هجمات محاكاة العناوين.

// VULNERABLE: manual bump not guaranteed to be canonical
#[account(seeds = [b"vault", user.key().as_ref()], bump = ctx.accounts.vault.bump)]
pub vault: Account<'info, Vault>,
// SECURE: omit the explicit bump value. Anchor v0.29.x derives and verifies
// the canonical bump automatically
#[account(
    seeds = [b"vault", user.key().as_ref()],
    bump,
)]
pub vault: Account<'info, Vault>,

في Anchor v0.29.x، احذف قيمة الزيادة الصريحة ودع Anchor يستنتج الزيادة القياسية. إذا قمت بتخزين الزيادة في بيانات الحساب، فقم بملئها أثناء init باستخدام ctx.bumps.vault.

لرسائل الخطأ التي تواجهها أثناء تطبيق أنماط الأمان هذه، راجع قسم استكشاف الأخطاء وإصلاحها.


استكشاف الأخطاء وإصلاحها في أخطاء Anchor الشائعة

تمثل الأخطاء أدناه المشكلات الأكثر شيوعًا التي يواجهها المطورون عند البناء باستخدام إطار عمل Anchor. يتضمن كل إدخال رسالة الخطأ الدقيقة وسببها والحل.

📌 ملاحظة: عدم تطابق الإصدارات يتسبب في غالبية فشل anchor build. تحقق من هذا الجدول أولاً قبل التحقيق في الأسباب الأخرى.

إصدار Anchorواجهة سطر أوامر Solana المطلوبةRust المطلوب
v0.29.xv1.18.x أو أحدث1.70.0 أو أحدث
v0.28.xv1.16.x أو أحدث1.69.0 أو أحدث

الخطأ 1: AccountNotInitialized (الحساب غير مُهيأ)

AnchorError caused by account: balance_account.
Error Code: AccountNotInitialized.
Error Number: 3012.

السبب: حاول برنامجك قراءة حساب بيانات غير موجود حاليًا على الكتلة. لم يتم استدعاء تعليم initialize (تهيئة).

الحل: قم باستدعاء تعليم initialize الخاص بك قبل أي تعليم يقرأ من الحساب. في الاختبارات، تأكد من تشغيل كتلة اختبار التهيئة (it) قبل كتلة اختبار الإيداع (deposit).


الخطأ 2: عدم تطابق الأنواع عند anchor build

error[E0308]: mismatched types
expected struct `anchor_lang::prelude::AccountInfo`
found struct `anchor_lang::accounts::signer::Signer`

السبب: يستخدم الكود الخاص بك صيغة تقييد الحساب من Anchor v0.26.x أو ما قبلها، والتي تغيرت في v0.29.x.

الحل: تحقق من وثائق Anchor الرسمية) لصيغة تقييد v0.29.x. قم بتشغيل avm use 0.29.0 للتأكد من أن إصدار واجهة سطر الأوامر لديك يطابق تبعية Cargo.toml الخاصة بك.


الخطأ 3: عدم توافق إصدار واجهة سطر أوامر Anchor/Solana

Error: RPC response error -32002: Transaction simulation failed

السبب: إصدار واجهة سطر أوامر Anchor لديك وإصدار واجهة سطر أوامر Solana غير متوافقين.

الحل:

avm use 0.29.0
solana --version     # Confirm Solana CLI is 1.18.x or later

الخطأ 4: عدم تطابق declare_id! بعد إعادة النشر

Error: Program Id mismatch

السبب: قمت بإعادة النشر إلى عنوان جديد ولكن declare_id!() في lib.rs لا يزال يحمل معرف البرنامج القديم.

الحل:

anchor keys sync
anchor build

الخطأ 5: عدم كفاية الأموال في Devnet

Error: Transaction simulation failed: insufficient funds

السبب: محفظة Devnet الخاصة بك لا تحتوي على ما يكفي من SOL لدفع رسوم النشر أو المعاملة.

الحل:

solana airdrop 2
solana balance

الخطأ 6: تجاوز البرنامج الثنائي لحد الحجم

Error: account data too small for instruction

السبب: يتجاوز البرنامج الثنائي المجمّع لديك حد حجم البرنامج الخاص بـ Solana للبرامج القابلة للترقية.

الحل: أضف تحسينات الإصدار إلى Cargo.toml الخاص بك:

[profile.release]
opt-level = "z"
lto = true

قم بإزالة التبعيات غير المستخدمة وعلامات الميزات من Cargo.toml و Anchor.toml الخاصة بك.

إذا كنت تواجه أخطاء في الإصدار، فارجع إلى دليل التثبيت وتحقق من تطابق إصدارات أدواتك مع جدول التوافق أعلاه.


إطار عمل Anchor وبيئة تطوير Solana

يشغل إطار عمل Anchor الغالبية العظمى من البرامج الإنتاجية المنشورة على مينيت Solana، بما في ذلك بروتوكولات في التمويل اللامركزي (DeFi)، والبنية التحتية لـ NFT، والحوكمة داخل الكتلة.

البروتوكولات الإنتاجية المبنية باستخدام Anchor:

  • Raydium: صانع السوق الآلي (AMM) وبروتوكول السيولة
  • Marinade Finance: بروتوكول التخزين السائل لـ SOL
  • Metaplex: معيار NFT، وبيانات وصفية للرموز، ومجموعة أدوات
  • Drift Protocol: بورصة مشتقات لامركزية
  • Kamino Finance: بروتوكول السيولة والإقراض
  • Jito: التخزين المدرك لـ MEV والبنية التحتية للمُدقّقين

تمثل بروتوكولات DeFi الفئة السائدة من البرامج المنشورة عبر Anchor. تعتمد البورصات اللامركزية، ومنصات الإقراض، ومجمّعات العائد، جميعها على إنتاجية Solana (حوالي 65,000 معاملة في الثانية في ظل ظروف مثالية، اعتبارًا من عام 2024) ورسومها المنخفضة (عادةً أقل من 0.001 دولار أمريكي لكل معاملة) لعملياتها الأساسية. يعكس نمو الأدوات المالية داخل الكتلة وتُمثيل أصول العالم الحقيقي كعملات رقمية على البلوكتشين على مستوى هذه البنية التحتية.

وفقًا لتقرير المطورين من Electric Capital (المتاح على electriccapital.com للأرقام الحالية)، نما قاعدة المطورين النشطين في Solana عامًا بعد عام خلال عام 2023 وبداية عام 2024. يساهم تبني المطورين المتزايد بشكل عام في صحة النظام البيئي للبلوكتشين، على الرغم من أنه لا ينبغي اعتبار هذا نصيحة استثمارية.

يعمل SOL كعملة رسوم لشبكة Solana. كل معاملة تستدعي برنامجًا داخل الكتلة تكلف كمية صغيرة من SOL (يمكن تداولها على بورصات العملات الرقمية الرئيسية بما في ذلك Coinbase و Binance). للحصول على بيانات سوق SOL الحالية، راجع بيانات أسعار SOL الحالية وبيانات السوق على CoinGecko.)

المزيد من المطورين الذين يبنون باستخدام Anchor يعني المزيد من البرامج المنشورة، مما يعني المزيد من الاستخدام النشط لشبكة Solana. هذا الارتباط هو ملاحظة حول ديناميكيات النظام البيئي، وليس إشارة استثمارية.


أسئلة متكررة حول إطار عمل Solana Anchor

ما هي لغة البرمجة التي تستخدمها Solana؟

تتم كتابة برامج Solana بلغة Rust. كما يدعم وقت التشغيل C و C++، ولكن Rust هي المعيار للتطوير الإنتاجي. بالنسبة للتعليمات البرمجية من جانب العميل، بما في ذلك الاختبارات والتفاعلات الأمامية والنصوص التي تستدعي برامجك، يتم استخدام TypeScript و JavaScript عبر حزمة npm @coral-xyz/anchor. يغطي إطار عمل Anchor كلا الطبقتين: Rust لمنطق البرنامج و TypeScript لكل ما يتفاعل معه.

هل Rust مطلوب لاستخدام إطار عمل Anchor؟

نعم. تتم كتابة برامج Anchor بلغة Rust، ولا يوجد مفر من ذلك. ومع ذلك، فإن وحدات الماكرو في Anchor تجرّد الأجزاء الأكثر تعقيدًا في Rust من تطوير Solana: التحقق من صحة الحسابات ونشر الأخطاء. يمكن لمطور لديه معرفة أساسية بـ Rust (الهياكل، الدوال، السمات، الملكية الأساسية) بناء ونشر برنامج Anchor عامل. الخبرة العميقة في Rust في العمر الافتراضي، وأنماط async، وأنواع Generics المتقدمة ليست مطلوبة للبدء. تنطبق مهاراتك في TypeScript أو JavaScript مباشرة على جانب العميل لكل مشروع Anchor.

ما هو عنوان مشتق من البرنامج (PDA) بعبارات بسيطة؟

عنوان مشتق من البرنامج (PDA) هو عنوان حساب يتحكم فيه برنامج بدلاً من مستخدم لديه مفتاح سري. نظرًا لأن عناوين PDA ليس لديها مفتاح سري، فإن البرنامج المالك فقط هو الذي يمكنه التفويض بمعاملات تتضمنها. بالنظر إلى نفس البذور ومعرف البرنامج، فإن عنوان PDA يؤدي دائمًا إلى نفس العنوان، مما يسمح للعملاء بالعثور على الحسابات التي يتحكم فيها البرنامج دون تخزين عناوينها بشكل منفصل. يتعامل Anchor مع اشتقاق PDA تلقائيًا من خلال تقييد seeds في هياكل حسابك. تُستخدم عناوين PDA بشكل شائع لحسابات الخزينة التي يتحكم فيها البرنامج، وحسابات الضمان، وتخزين بيانات المستخدم الفردي.

هل يمكن بناء NFTs باستخدام إطار عمل Anchor؟

نعم. تم بناء الغالبية العظمى من البنية التحتية لـ NFT الخاصة بـ Solana على Anchor. معيار Metaplex، الذي يحدد البيانات الوصفية للرموز، وهيكل المجموعة، والحقوق الرقمية لـ NFTs على Solana، هو نفسه برنامج يعتمد على Anchor. أي منصة NFT على Solana تتفاعل مع برامج Metaplex عبر استدعاءات بين البرامج (CPI) باستخدام crate anchor-spl، الذي يوفر أغلفة آمنة من حيث النوع لتعليمات SPL Token.

نعم. يتمت صيانة Anchor بواسطة Coral XYZ وهو المعيار الفعلي لتطوير برامج Solana اعتبارًا من عام 2024. الإصدار المستقر الحالي هو v0.29.x. يتلقى مستودع Anchor على GitHub (coral-xyz/anchor) إصدارات منتظمة تتتبع تحديثات وقت تشغيل Solana. تستمر بروتوكولات الإنتاج الرئيسية، بما في ذلك Raydium وMarinade Finance وMetaplex، في البناء على Anchor، مما يؤكد جاهزيته للإنتاج.

كيف يقارن Anchor بـ Hardhat الخاص بـ Ethereum؟

يؤدي Anchor وHardhat أدوارًا متشابهة على سلاسل البلوكتشين الخاصة بهما: كلاهما يوفر هيكل المشروع، وبيئة اختبار، وأدوات نشر. تبدأ الاختلافات بالبنية التحتية الأساسية. يستهدف Hardhat نموذج العقود المعتمد على الحالة في Ethereum، حيث يحتفظ العقد الذكي بكل من منطقه وحالته. بينما يستهدف Anchor نموذج البرنامج عديم الحالة في Solana، حيث تعيش البرامج والبيانات في حسابات منفصلة. تختلف اللغات أيضًا: تستخدم مشاريع Hardhat لغة Solidity للعقود وJavaScript أو TypeScript للاختبارات؛ بينما تستخدم مشاريع Anchor لغة Rust للبرامج وTypeScript للاختبارات. تختلف تكاليف المعاملات أيضًا بشكل كبير: فعادة ما تكلف معاملات Solana أقل من 0.001 دولار، بينما تختلف رسوم غاز Ethereum ويمكن أن تصل إلى 1 دولار إلى 50 دولارًا أو أكثر لكل معاملة. لإجراء مقارنة كاملة جنبًا إلى جنب، راجع جداول مقارنة Anchor مقابل البدائل.

كم من الوقت يستغرق تعلم إطار عمل Anchor؟

يمكن للمطور الذي لديه خبرة في TypeScript أو JavaScript وليس لديه معرفة سابقة بـ Rust بناء ونشر برنامج Anchor أساسي على devnet عادةً في غضون يوم إلى يومين باستخدام دليل منظم. الانتقال من برنامج أساسي إلى بروتوكول DeFi للإنتاج يستغرق من أسابيع إلى شهور، اعتمادًا على تعقيد البرنامج وعمق الخبرة في Rust. منحنى تعلم Rust هو المتغير الأساسي. المطورون الذين يستثمرون الوقت في أساسيات Rust جنبًا إلى جنب مع Anchor يشهدون تقدمًا أسرع في البرامج غير التقليدية.

مكتبة برامج Solana (SPL) هي مجموعة من البرامج التي تم تدقيقها ونشرها مسبقًا على Solana للعمليات الشائعة. برنامج SPL Token هو المعادل في Solana لمعيار ERC-20، ويتم تنفيذه كبرنامج مشترك داخل الكتلة بدلاً من قالب عقد يقوم كل مشروع بنشره بشكل مستقل. يتكامل Anchor مع SPL من خلال حزمة anchor-spl التي توفر أغلفة آمنة للأنواع لتعليمات SPL Token بما في ذلك transfer و mint_to و burn. تعد SPL أيضًا الأساس للبيانات الوصفية لرموز NFT من خلال برنامج Metaplex.

ما هو إثبات التاريخ (PoH) في Solana؟

إثبات التاريخ (PoH) هو آلية لتسجيل الوقت بطريقة تشفيرية تستخدمها Solana لترتيب المعاملات قبل وصولها إلى المدققين من أجل الإجماع. وبدلاً من مطالبة المدققين بالتواصل للاتفاق على ترتيب المعاملات، يدمج PoH تسلسلاً زمنيًا يمكن التحقق منه مباشرة في البلوكتشين. يقلل هذا من أعباء التنسيق لبروتوكولات الإجماع التقليدية، وهو أحد الأسباب التي تجعل Solana تحقق حوالي 65,000 معاملة في الثانية في ظل الظروف المثالية اعتبارًا من عام 2024.

هل Solana جيدة لتطوير العقود الذكية؟

تعد Solana مناسبة تمامًا للتطبيقات التي تكون فيها سرعة المعاملات والتكلفة من القيود الأساسية: مثل بروتوكولات DeFi عالية التردد، وأسواق NFT التي تتضمن العديد من المعاملات الصغيرة، وألعاب البلوكتشين. يتطلب نموذج الحساب الخاص بها تعلمًا مسبقًا أكثر من Ethereum، لكن إطار عمل Anchor يقلل من هذا الاحتكاك بشكل كبير. يعتمد اختيار Solana كخيار مناسب على ملف تعريف تطبيقك. تقدم Ethereum نظامًا بيئيًا أكبر وتاريخًا أكثر رسوخًا في تدقيق الأمان، بينما توفر Solana رسومًا أقل وإنتاجية أعلى لحالات الاستخدام التي تستفيد من كليهما.


الخلاصة: هل إطار عمل Anchor مناسب لمشروع Solana الخاص بك؟

بالنسبة للعديد من سير عمل تطوير تطبيقات Solana، يعد إطار عمل Anchor نقطة انطلاق شائعة، بينما تظل لغة Rust الأصلية ذات أهمية عندما يكون التحكم من المستوى الأدنى مطلوبًا.

يقلل Anchor من الكود البرمجي المتكرر في تطوير Rust الأصلي بشكل كبير. البرامج التي تتطلب مئات الأسطر في كود Solana الأصلي تستغرق جزءًا بسيطًا من ذلك باستخدام نظام الماكرو في Anchor. إنه يفرض أمان الحساب من خلال نظام القيود الخاص به، ويكتشف أخطاء الملكية والتفويض في وقت الترجمة أو وقت التشغيل بدلاً من مرحلة الإنتاج. كما يقوم بإنشاء عميل TypeScript تلقائيًا من IDL، مما يمنح مطوري JavaScript واجهة مألوفة ومنظمة لبرامجهم دون كتابة Rust في جانب العميل.

يستحق تطوير Rust الأصلي الدراسة فقط عندما يتطلب برنامجك تحكمًا دقيقًا في استهلاك وحدة الحساب أو عندما تتعارض تجريدات Anchor بشكل حقيقي مع بنية غير عادية. بالنسبة للأغلبية العظمى من البرامج، بما في ذلك بروتوكولات DeFi ومنصات NFT والمنظمات اللامركزية المستقلة (DAOs) وأنظمة حظر الرموز، فإن Anchor هو المكان الذي يجب أن تبدأ منه.

الخطوات التالية:

  1. انشر برنامج تتبع الرصيد من هذا الدليل إلى devnet باستخدام الأمر anchor deploy --provider.cluster devnet
  2. استكشف وثائق Anchor الرسمية على anchor-lang.com للحصول على مرجع API الكامل والميزات المتقدمة
  3. تصفح مستودع أمثلة Anchor على GitHub للبرامج ذات أنماط الإنتاج
  4. انضم إلى Anchor Discord أو Solana Stack Exchange للحصول على دعم المجتمع عند مواجهة مشكلات

البرنامج الذي نشرته في هذا الدليل حقيقي: فهو موجود على devnet الخاص بـ Solana، ويقبل المعاملات، ويخزن الحالة داخل الكتلة. هذا هو الأساس الذي يُبنى عليه كل تطبيق Solana في مرحلة الإنتاج.

أدلة تقنية ذات صلة بـ Solana

يمكن للمطورين الذين يتابعون SOL جنبًا إلى جنب مع أدوات النظام البيئي استشارة صفحة سعر SOL) كمرجع منفصل للسوق؛ فهي لا تتحقق من أمان البرنامج أو جاهزية النشر.