كنت أفترض سابقاً أن بناء NFT على Solana يعني الصراع مع Metaplex. كان هذا هو المسار الذي تقترحه كل الدروس التعليمية: تشغيل Candy Machine، وإدارة حسابات البيانات الوصفية (metadata accounts)، والموازنة بين برامج منفصلة فقط لإرفاق اسم وصورة برمز (token). اتضح أن هذا الافتراض قد عفا عليه الزمن. فقد اختزل برنامج Token Extensions، المعروف أيضاً باسم Token-2022، هذا التعقيد في عملية السك (mint) نفسها. يمكنك الآن إنشاء NFT يعمل بكامل وظائفه دون المساس ببرنامج بيانات وصفية أو تمويل حسابات إضافية. كل ما عليك فعله هو تفعيل بعض العلامات (flags)، وكتابة البيانات مباشرة في حساب السك (mint account)، وتكون قد انتهيت.
يغير هذا طريقة تفكير المطورين في الأصول الرقمية على Solana. في تطوير الويب التقليدي، يبدو الـ NFT كبنية بيانات متميزة، شيء يتطلب جدولاً ومخططاً (schema) خاصاً به. أما على Solana، فإن الواقع أكثر بساطة وأناقة. الـ NFT ليس كائناً خاصاً تُديره بروتوكولات خارجية، بل هو ببساطة حساب سك (mint account) تم تكوينه بعرض (supply) قدره واحد بالضبط وصفر من المنازل العشرية (decimals). يسمح لك الرمز القياسي (standard token) بتقسيم الوحدات لأنه يحمل عرضاً كبيراً وعدداً من المنازل العشرية. أما الـ NFT فيقوم بقفل العرض عند وحدة واحدة غير قابلة للتجزئة. وكل ما يجعله فريداً يعيش في ملحقات (extensions) تعمل جنباً إلى جنب مع حساب السك الأساسي هذا.
الطريقة القديمة والطريقة الجديدة
قبل Token Extensions، كان المكدس البرمجي (stack) المعتاد يتضمن برنامج SPL Token لعملية السك نفسها، بالإضافة إلى Metaplex للبيانات الوصفية، والمجموعات (collections)، وأحياناً الفهرسة خارج السلسلة (off-chain indexing). كانت البيانات الوصفية توضع في حسابات منفصلة، مرتبطة بعناوين كان عليك تتبعها. كان الأمر يعمل، لكنه زاد من مساحة التعقيد (surface area). فالمزيد من الحسابات يعني المزيد من الإيجار (rent)، ومزيد من مسارات التوقيع (signing paths)، ومزيد من المنطق في جانب العميل (client-side logic) لاستخلاص الصورة الكاملة للرمز.
يستبدل Token Extensions هذا التشتت عبر دمج القدرات مباشرة في عملية السك. هل تحتاج إلى اسم، ورمز، ورابط لوسائط خارج السلسلة؟ قم بتفعيل ملحق البيانات الوصفية (metadata extension). هل تحتاج إلى تجميع الرموز في مجموعة؟ استخدم ملحقي Group و Member. يصبح حساب السك هو المصدر الوحيد للحقيقة. بالنسبة للمطورين المعتادين على قواعد البيانات 관계ية (relational databases)، فإن هذا التحول يشبه الانتقال من بنية الخدمات المصغرة الموزعة (distributed microservices architecture) إلى جدول مُطبع (normalized table) مع مفاتيح خارجية (foreign keys) مصممة جيداً.
تشريح الـ NFT القائم على الملحقات (Extensions)
يتطلب إنشاء NFT باستخدام Token Extensions فهم ما يجعل الرمز غير قابل للاستبدال (non-fungible) على هذه الشبكة بالضبط. يجب أن يكون العرض (supply) مساوياً لواحد، ويجب أن تكون المنازل العشرية (decimals) مساوية للصفر. تمنع هاتان المجموعتان التجزئة (fractionalization). وبمجرد ضبط هذه المعايير، يمكنك تفعيل الملحقات التي تخزن حقولاً إضافية مباشرة في حساب السك (mint account).
يحتوي ملحق البيانات الوصفية (metadata extension) على الاسم، والرمز، وURI. يشير رابط URI هذا إلى ملف JSON، مستضاف عادةً على تخزين لامركزي أو خادم ويب قياسي، والذي يصف الصورة والسمات والخصائص. لا يوجد حساب بيانات وصفية منفصل لاكتشافه وإلغاء تسلسله (deserialize). البيانات توجد في حساب السك نفسه، مما يعني أن المستكشفات (explorers)، والمحافظ (wallets)، وبرمجيات العميل يمكنها قراءة الهوية الأساسية للرمز من خلال فحص حساب واحد فقط.
لقد اختبرت هذا بنفسي على devnet. قمت بإنشاء عملية سك جديدة مع تفعيل ملحق البيانات الوصفية، ثم كتبت الاسم والرمز مباشرة في حالة السك (mint state). نجحت المعاملة، وظهرت النتيجة فوراً في Solana Explorer. لم يكن هناك حساب ثانٍ لتمويله أو تحديد موقعه. كانت البساطة مذهلة بعد أسابيع من العمل مع بيانات Metaplex الوصفية متعددة الحسابات.
بناء المجموعات مثل صفوف قواعد البيانات
كانت المجموعات (Collections) هي الخطوة المنطقية التالية. في النموذج القديم، كان تجميع الـ NFTs يعني عادةً الاعتماد على Metaplex Certified Collections أو سجلات خارج السلسلة (off-chain registries). يقدم Token Extensions عنصرين أساسيين (primitives): ملحق Group وملحق Member.
إليك كيفية تدفق المنطق: تقوم بإنشاء عملية سك واحدة تعمل كرأس للمجموعة (collection header) وتفعل ملحق Group عليها. ثم، لكل NFT فردي في المجموعة، تقوم بإنشاء عملية سك مع تفعيل ملحق Member. يخزن كل حساب سك عضو (member mint) مؤشراً يعود إلى عنوان سك المجموعة (collection mint address). تتصرف هذه العلاقة تماماً مثل المفتاح الخارجي (foreign key) في قاعدة بيانات 관계ية. يوجد صف المجموعة مرة واحدة، ويشير كل صف عضو إليه دون تكرار هوية المجموعة.
لقد بنيت مجموعة اختبار صغيرة بهذه الطريقة على devnet. حملت عملية سك المجموعة الرئيسية علامة المجموعة (group flag)، بينما حملت الرموز الفردية علامة العضو (member flag) وأشارت إلى العنوان الأب (parent address). أعطاني الاستعلام في السلسلة هيكلاً نظيفاً وقابلاً للتنقل (traversable structure). لم تكن هناك حاجة لفهرس من طرف ثالث (third-party indexer) لتخمين ما إذا كانت الرموز تنتمي إلى بعضها البعض. العلاقة صريحة وموجودة على السلسلة (on-chain).
المخطط المفتوح والتجارب على السلسلة (On-Chain)
ثمة تفصيل واحد يبرز بوضوح، وهو المخطط المفتوح (open schema) لملحق البيانات الوصفية (metadata extension). فغالبًا ما تفرض المعايير القديمة قائمة حقول ثابتة، وإذا أردت تخزين شيء غير قياسي على السلسلة (on-chain)، فستجد نفسك مضطرًا لوضعه في ملف JSON خارج السلسلة (off-chain) أو الالتفاف حول تخطيطات الحسابات الجامدة.
تتبع Token Extensions نهجًا مختلفًا. نظرًا لأن ملحق البيانات الوصفية يقبل حقولاً مخصصة، فقد تمكنت من إضافة سمة ندرة (rarity attribute) مباشرة إلى حساب الصك (mint account). قمت بكتابة الحقل، وأرسلت المعاملة، ثم قمت بتحديث Solana Explorer. ظهرت قيمة الندرة على الفور بجانب الاسم والرمز. بالنسبة لمطوري الألعاب أو أي شخص يبني أصولاً ديناميكية، فإن هذه المرونة أمر بالغ الأهمية؛ حيث يمكنك إظهار السمات الهامة على السلسلة دون الحاجة إلى مُحقق خارجي لتحليل ملفات JSON.
الفجوة خارج السلسلة (Off-Chain): معرفات الموارد الموحدة (URIs) والتخزين المؤقت (Caching)
رغم كل أناقة التخزين على السلسلة، فقد برز درس واحد بوضوح: الهوية لا تزال تعيش خارج السلسلة (off-chain). فعملية الصك (mint) لا تخزن صورتك، بل تخزن URI. عندما قمت بتحديث هذا الـ URI وثبّتُّ التغيير على الـ devnet، عكست السلسلة المؤشر الجديد على الفور، وأظهرت مستكشفات الكتل (Block explorers) الرابط المحدث دون تأخير.
لكن محفظتي تأخرت؛ حيث استمرت في عرض الصورة القديمة لعدة دقائق، متمسكةً بعرض نسخة مخزنة مؤقتًا (cached version) بينما كانت البيانات الأساسية على السلسلة قد تغيرت بالفعل. هذا واقع عملي يجب على المطورين التخطيط له. فسجل Solana سريع، وأوقات التأكيد قصيرة، ومع ذلك، فإن الطبقة المرئية التي يتفاعل معها المستخدمون تعتمد على ذاكرة التخزين المؤقت لـ HTTP، وانتشار شبكة توصيل المحتوى (CDN)، وفترات التحديث الخاصة بكل محفظة. إذا كنت تبني NFT ديناميكيًا يتغير بناءً على أحداث في العالم الحقيقي، فلا يمكنك افتراض أن المستخدم سيرى التغيير في اللحظة التي تتم فيها المعاملة. أنت بحاجة إلى استراتيجيات لكسر التخزين المؤقت (cache-busting)، أو استخدام الإصدارات (versioning) في مسارات الـ URI الخاصة بك، أو وضع محفزات تحديث صريحة في الواجهة الأمامية (frontend) الخاصة بك.
ما الذي سيأتي بعد ذلك
لقد وضعت تجاربي على الـ devnet حجر الأساس لمشروع أكثر ديناميكية. الخطوة التالية هي مجموعة (collection)
