المؤلف: @Web3Mario
الملخص: بعد المقالة السابقة حول إدخال تقنية TON، قمت بدراسة وثائق تطوير TON الرسمية بعمق خلال هذه الفترة، وأشعر أنه لا تزال هناك بعض العوائق أمام ذلك يبدو أن محتوى المستند الحالي أشبه بوثيقة تطوير داخلية، وهي ليست مناسبة جدًا للمطورين الجدد، لذلك أحاول فرز سلسلة من المقالات حول تطوير مشروع TON Chain بناءً على مسار التعلم الخاص بي يمكن أن يساعد الجميع على البدء بسرعة في تطوير TON DApp. هناك بعض المساعدة. إذا كان هناك أي أخطاء في الكتابة، فنحن نرحب بتصحيح لي والتعلم معا.
ما هي الاختلافات بين تطوير NFT في EVM وتطوير NFT على سلسلة TON
عادةً ما يكون إصدار FT أو NFT هو الحاجة الأساسية لمطوري التطبيقات اللامركزية. لذلك أستخدم هذا أيضًا كنقطة دخول للتعلم. أولاً، دعونا نفهم الاختلافات التالية بين تطوير NFT في مكدس تقنية EVM وسلسلة TON. غالبًا ما تختار NFTs المستندة إلى EVM أن ترث معيار ERC-721. يشير ما يسمى بـ NFT إلى نوع غير قابل للتجزئة من الأصول المشفرة، وكل أصل فريد من نوعه، أي أن له خصائص حصرية معينة. يعد ERC-721 نموذج تطوير شائع لهذا النوع من الأصول. دعونا نلقي نظرة على الوظائف التي يحتاج عقد ERC721 المشترك إلى تنفيذها والمعلومات التي يتم تسجيلها. الصورة أدناه هي واجهة ERC721. ويمكن ملاحظة أنه على عكس FT، فإن ما يجب إدخاله في واجهة النقل هو الرمز المميز الذي سيتم نقله وليس المبلغ. يعد معرف الرمز المميز هذا أيضًا المظهر الأساسي لتفرد أصول NFT. بالطبع، من أجل حمل المزيد من السمات، يتم عادةً تسجيل البيانات الوصفية لكل معرف مميز. هذه البيانات الوصفية عبارة عن رابط خارجي يحفظ بيانات NFT أخرى قابلة للتطوير، مثل كروابط لصور PFP، وأسماء خصائص معينة، وما إلى ذلك.
لأولئك الذين هم على دراية بـ Solidity أو على دراية مع التطوير الموجه للكائنات، من السهل بالنسبة للمستثمرين تنفيذ مثل هذا العقد الذكي، ما عليك سوى تحديد أنواع البيانات المطلوبة في العقد، مثل بعض علاقات رسم الخرائط الرئيسية، وتطوير منطق التعديل المقابل لهذه البيانات وفقًا للمطلوب. تنفيذ وظائف NFT.
ومع ذلك، كل شيء مختلف في TON Chain هناك سببان أساسيان للاختلاف:
تخزين. يتم تنفيذ البيانات الموجودة في TON بناءً على الخلية، ويتم تنفيذ خلية نفس الحساب من خلال رسم بياني غير دوري موجه. وهذا يعني أن البيانات التي يجب تخزينها لا يمكن أن تنمو بدون حدود، لأنه بالنسبة للرسم البياني غير الدوري الموجه، يتم تحديد تكلفة الاستعلام حسب عمق البيانات. عندما يمتد العمق إلى ما لا نهاية، قد تكون تكلفة الاستعلام مرتفعة جدًا، مما يؤدي إلى العقد عالق في مشكلة طريق مسدود.
من أجل متابعة أداء عالي التزامن، تخلت TON عن بنية التنفيذ التسلسلي واعتمدت بدلاً من ذلك نموذج تطوير مصمم خصيصًا للتوازي، وهو نموذج الممثل، لإعادة بناء بيئة التنفيذ. هذا له تأثير. لا يمكن استدعاء العقود الذكية إلا بشكل غير متزامن عن طريق إرسال ما يسمى بالرسائل الداخلية. لاحظ أنه سواء كان نوع الاتصال للقراءة فقط، فيجب اتباعه أيضًا يجب النظر بعناية في كيفية التعامل مع استعادة البيانات في حالة فشل مكالمة غير متزامنة.
وبطبيعة الحال، تمت مناقشة الاختلافات التقنية الأخرى بالتفصيل في المقالة السابقة للتركيز على تطوير العقود الذكية، لذلك لن يتم مناقشتها. يُحدث مبدأا التصميم المذكوران أعلاه فرقًا كبيرًا بين تطوير العقود الذكية في TON وEVM. في المناقشة الأولية، نعلم أن عقد NFT يحتاج إلى تحديد بعض علاقات التعيين، أي رسم الخرائط لحفظ البيانات المتعلقة بـ NFT. والأهم هو المالكين. يقوم هذا التعيين بتخزين علاقة التعيين لعنوان مالك NFT المطابق لمعرف رمزي معين، والذي يحدد ملكية NFT. يعد النقل تعديلاً للملكية. نظرًا لأن بنية البيانات هذه يمكن أن تكون لا حدود لها من الناحية النظرية، فيجب تجنبها قدر الإمكان. لذلك، يوصى رسميًا باستخدام وجود هياكل بيانات غير محدودة كمعيار للمشاركة. أي أنه عندما تكون هناك متطلبات مماثلة لتخزين البيانات، يتم استخدام نموذج العقد الرئيسي والعبد بدلاً من ذلك، وتتم إدارة البيانات المقابلة لكل مفتاح عن طريق إنشاء عقود من الباطن. وإدارة المعلمات العالمية من خلال العقد الرئيسي، أو المساعدة في التعامل مع تفاعل المعلومات الداخلية بين العقود من الباطن.
وهذا يعني أن NFTs في TON تحتاج أيضًا إلى التصميم باستخدام بنية مماثلة، كل NFT عبارة عن عقد من الباطن مستقل، والذي يحفظ البيانات الحصرية مثل عنوان المالك والبيانات الوصفية وما إلى ذلك، والبيانات العالمية. مثل اسم NFT والرمز وإجمالي العرض وما إلى ذلك، تتم إدارتها من خلال عقد رئيسي.
بعد توضيح البنية، فإن الخطوة التالية هي حل المتطلبات الوظيفية الأساسية نظرًا لاعتماد طريقة العقد الرئيسي والتابع، فمن الضروري توضيح الوظائف التي يتم تنفيذها بواسطة العقد الرئيسي التي يحملها المقاولون من الباطن، وما هي المعلومات الداخلية التي يتم تبادلها بين الطرفين، وكيفية استرجاع البيانات السابقة عند حدوث خطأ في التنفيذ. عادة، قبل تطوير مشروع معقد واسع النطاق، من الضروري تمرير مخطط الفصل وتوضيح تدفق المعلومات بين بعضها البعض، والتفكير بعناية في منطق التراجع بعد فشل الاستدعاء الداخلي، بالطبع، تطوير NFT أعلاه بسيط ، ولكن يمكنه أيضًا إجراء تحقق مماثل.
تعلم وتطوير عقود TON الذكية من الكود المصدري
اختار TON تصميم لغة مكتوبة بشكل ثابت تشبه لغة C تسمى Func كلغة تطوير العقود الذكية، ثم الخطوة التالية هي دعونا نتعلم كيفية تطوير عقود TON الذكية من الكود المصدري، لقد اخترت مثال NFT في مستند TON الرسمي لتقديمه. في هذه الحالة، يتم تنفيذ مثال TON NFT بسيط. دعونا نلقي نظرة على هيكل العقد، والذي ينقسم إلى عقدين وظيفيين وثلاث مكتبات ضرورية.
يعتمد هذان العقدان الوظيفيان الرئيسيان على التصميم بناءً على المبادئ المذكورة أعلاه، دعونا أولاً نلقي نظرة على كود العقد الرئيسي nft-collection:
يقدم هذا نقطة المعرفة الأولى، وهي كيفية تخزين البيانات بشكل مستمر في عقود TON الذكية. نحن نعلم أن التخزين المستمر للبيانات في Solidity تتم معالجته تلقائيًا بواسطة EVM وفقًا لنوع المعلمات في ظل الظروف العادية، سيتم الحفاظ على متغيرات الحالة للعقود الذكية تلقائيًا وتخزينها وفقًا لأحدث قيمة بعد التنفيذ، ولا يحتاج المطورون إلى مراعاة هذه العملية. لكن هذا ليس هو الحال في Func، يحتاج المطورون إلى تنفيذ منطق المعالجة المقابل بأنفسهم، وهذا الموقف مشابه إلى حد ما لكيفية تفكير C وC++ في عملية GC، لكن لغات التطوير الجديدة الأخرى عادةً ما تقوم بأتمتة هذا الجزء من المنطق. . دعونا نلقي نظرة على الكود أولاً، نقدم بعض المكتبات المطلوبة، ثم نرى أن الوظيفة الأولى Load_data تُستخدم لقراءة البيانات المخزنة باستمرار، ومنطقها هو إرجاع خلية تخزين العقد المستمر أولاً من خلال get_data يتم تنفيذه بواسطة المعيار الذي تنفذه المكتبة stdlib.fc، ويمكن عادةً استخدام بعض الوظائف كوظائف النظام.
نوع القيمة المرجعة لهذه الوظيفة هو الخلية، وهو نوع الخلية في TVM. في المقدمة السابقة، نعلم بالفعل أن جميع البيانات المستمرة في TON blockchain يتم تخزينها في شجرة الخلايا. تحتوي كل خلية على ما يصل إلى 1023 بت من البيانات العشوائية وما يصل إلى أربعة إشارات إلى خلايا أخرى. يتم استخدام الخلايا كذاكرة في TVM القائم على المكدس. ما يتم تخزينه في الخلية هو بيانات مشفرة بشكل مضغوط للحصول على بيانات نصية محددة، يجب تحويل الخلية إلى نوع يسمى شريحة. يمكن تحويل الخلية إلى نوع الشريحة من خلال وظيفة begin_parse، ومن ثم يمكن الحصول على البيانات الموجودة في الخلية عن طريق تحميل بتات البيانات والمراجع إلى خلايا أخرى من الشريحة. لاحظ أن طريقة الاستدعاء في السطر 15 هي السكر النحوي في func الذي يستدعي الوظيفة الثانية مباشرة على القيمة المرجعة للوظيفة الأولى. وأخيرًا قم بتحميل البيانات المقابلة بالترتيب وفقًا لترتيب ثبات البيانات. لاحظ أن هذه العملية تختلف عن الصلابة ولا يتم استدعاؤها بناءً على علامة التجزئة، لذلك لا يمكن العبث بترتيب المكالمات.
في وظيفة save_data، يكون المنطق مشابهًا، باستثناء أن هذه عملية عكسية، والتي تقدم نقطة المعرفة التالية، وهو منشئ النوع الجديد، وهو نوع منشئ الخلايا. يمكن تخزين بتات البيانات والمراجع إلى الخلايا الأخرى في المنشئين، والتي يمكن بعد ذلك تحويلها إلى خلايا جديدة. قم أولاً بإنشاء مُنشئ من خلال الوظيفة القياسية begin_cell، وقم بتخزين الوظائف ذات الصلة من خلال الوظائف ذات الصلة بالمتجر بدورها، لاحظ أن ترتيب الاستدعاء أعلاه يجب أن يكون متوافقًا مع ترتيب التخزين هنا. أخيرًا، يتم استخدام end_cell لإكمال بناء الخلية الجديدة. وفي هذا الوقت، تتم إدارة الخلية في الذاكرة، وأخيرًا، يمكن إكمال التخزين المستمر للخلية من خلال مجموعة_البيانات الخارجية.
دعونا بعد ذلك نلقي نظرة على الوظيفة المتعلقة بالأعمال، نحتاج أولاً إلى تقديم نقطة المعرفة التالية، وهي كيفية إنشاء عقد جديد من خلال العقد، والذي سيتم استخدامه بشكل متكرر في بنية السيد والعبد التي تم تقديمها للتو. نحن نعلم أنه في TON، يتم تنفيذ المكالمات بين العقود الذكية عن طريق إرسال رسائل داخلية. يتم تحقيق ذلك من خلال رسالة تسمى send_raw_message. لاحظ أن المعلمة الأولى هي الخلية المشفرة بالرسالة، والمعلمة الثانية هي بت التعريف، والتي يتم استخدامها للإشارة إلى الاختلاف في طريقة تنفيذ المعاملة في TON يوجد حاليًا 3 أوضاع للرسائل و3 علامات للرسائل لوضع تنفيذ إرسال الرسالة. يمكن دمج وضع واحد مع إشارات متعددة (ربما لا شيء) للحصول على الوضع المطلوب. الجمع يعني فقط ملء مجموع قيمها. ويرد أدناه جدول وصف الأوضاع والأعلام:
< p>لذلك دعونا نلقي نظرة على الوظيفة الرئيسية الأولى، Submit_nft_item. كما يوحي الاسم، هذه وظيفة تُستخدم لإنشاء أو إرسال مثيل NFT جديد، بعد إجراء بعض العمليات لتشفير رسالة، أرسل العقد الداخلي من خلال send_raw_message وحدد الإرسال يتم مسح بت العلم للعلم 1، ويتم استخدام الرسوم المحددة في التشفير فقط كرسوم الغاز لهذا التنفيذ. بعد المقدمة أعلاه، يمكننا أن ندرك بسهولة أن قاعدة الترميز هذه يجب أن تتوافق مع طريقة إنشاء عقد ذكي جديد. لذلك دعونا نلقي نظرة على كيفية تنفيذه.
دعونا نلقي نظرة مباشرة على السطر 51. الوظيفتان المذكورتان أعلاه هما وظائف مساعدة تستخدم لإنشاء المعلومات المطلوبة للرسالة، لذلك سننظر إليها لاحقًا. هذه عملية تشفير لإنشاء رسائل داخلية ذكية العقود، بعض الأرقام في المنتصف هي في الواقع بعض بتات التعريف، المستخدمة لشرح متطلبات الرسالة الداخلية. تم تقديم نقطة المعرفة التالية هنا. اختار TON لغة ثنائية تسمى TL-B لوصف طريقة تنفيذ الرسالة. ووفقًا لـ تعيين بتات إشارة مختلفة لتنفيذ الرسائل الداخلية لوظائف محددة، فإن أسهل سيناريوهين للاستخدام يمكن التفكير فيهما هما إنشاء عقد جديد واستدعاءات وظائف العقد المنشورة. تتوافق الطريقة الموجودة في السطر 51 مع الطريقة السابقة، مما يؤدي إلى إنشاء عقد عنصر nft جديد، والذي يتم تحديده بشكل أساسي في الأسطر 55 و56 و57. بادئ ذي بدء، السلسلة الكبيرة من الأرقام في السطر 55 هي سلسلة من بتات التعريف. لاحظ أن معلمة الإدخال الأولى لـ store_uint هي القيمة، والثانية هي طول البت، الذي يحدد ما إذا كانت الرسالة الداخلية قد تم إنشاؤها بواسطة العقد. ، آخر ثلاث بتات للعلامات، وبتات القيمة الثنائية المقابلة هي 111 (4+2+1 بالنظام العشري)، وتشير أول بتتين منها إلى أن الرسالة ستكون مصحوبة ببيانات StateInit، وهذه البيانات هي الكود المصدري لـ العقد الجديد والبيانات المطلوبة للتهيئة. تشير بتة العلامة الأخيرة إلى مرفق الرسالة الداخلية، أي أنه من المتوقع تنفيذ المنطق ذي الصلة والمعلمات المطلوبة. لذلك، سترى أن البيانات المكونة من ثلاثة أرقام لم يتم تعيينها في السطر 66 من الكود، مما يشير إلى استدعاء دالة للعقد المنشور. يمكن العثور على قواعد الترميز التفصيلية هنا.
ثم تتوافق قواعد تشفير StateInit مع 49 سطرًا من التعليمات البرمجية، ويتم حسابها من خلال Calculate_nft_item_state_init. لاحظ أن تشفير بيانات Stateinit يتبع أيضًا قاعدة ترميز TL-B المعمول بها، بالإضافة إلى بعض بتات العلم يتضمن جزأين من رمز العقد الجديد وبيانات التهيئة. يجب أن يكون ترتيب تشفير البيانات متسقًا مع ترتيب تخزين خلايا الثبات المحددة في العقد الجديد. كما ترون في السطر 36، تتضمن بيانات التهيئة item_index، وهو مشابه لـ tokenId في ERC721، وعنوان العقد الحالي الذي تم إرجاعه بواسطة الوظيفة القياسية my_address، وهو Collection_address، ويتوافق ترتيب هذه البيانات مع الإعلان الموجود nft-item.
نقطة المعرفة التالية هي أنه في TON، يمكن لجميع العقود الذكية التي لم يتم إنشاؤها حساب عناوينها التي تم إنشاؤها مسبقًا، وهذا مشابه لوظيفة create2 في Solidity، وتتكون من جزأين تم ربط بت تعريف سلسلة العمل وقيمة التجزئة الخاصة بـstateinit معًا في المقدمة السابقة، نعلم بالفعل أن الأول يحتاج إلى تحديد من أجل التوافق مع بنية التجزئة اللانهائية لـ TON، وهي قيمة موحدة حاليًا. تم الحصول عليها من سلسلة عمل الوظيفة القياسية. يتم الحصول على الأخير من خلال الوظيفة القياسية cell_hash. لذا، وبالعودة إلى هذا المثال، فإن دالة Calculate_nft_item_address هي دالة تقوم بحساب عنوان العقد الجديد مسبقًا. وقم بتشفير القيمة التي تم إنشاؤها في الرسالة الموجودة على السطر 53 كعنوان استلام الرسالة الداخلية. يتوافق nft_content مع استدعاء التهيئة للعقد الذي تم إنشاؤه وسيتم تقديم التنفيذ المحدد في المقالة التالية.
أما بالنسبة لـ send_royalty_params، فيجب أن تكون استجابة للرسالة الداخلية لطلب القراءة فقط. في المقدمة السابقة، أكدنا بشكل خاص على أن الرسالة الداخلية في TON لا تحتوي فقط على عمليات قد تعدل البيانات ولكن أيضًا للقراءة فقط، يجب أيضًا تنفيذ العملية بهذه الطريقة، لذا فإن العقد عبارة عن مثل هذه العملية، بادئ ذي بدء، تجدر الإشارة إلى أن السطر 67 يمثل علامة وظيفة رد الاتصال الخاصة بالطالب بعد الاستجابة للطلب. قم بتدوينها كبيانات تم إرجاعها، على التوالي، فهرس العناصر وبيانات حقوق الملكية المقابلة.
دعونا نقدم نقطة المعرفة التالية. لا يوجد سوى مدخلين موحدين للعقود الذكية في TON، يُسمىان recv_internal وrecv_external مدخل اتصال موحد لجميع الرسائل الخارجية يحتاج المطورون إلى استخدام طريقة تشبه التبديل للرد على الطلبات المختلفة بناءً على بتات العلامات المختلفة المحددة بواسطة الرسالة داخل الوظيفة وفقًا للمتطلبات فوق. بالعودة إلى هذا المثال، قم أولاً بإجراء فحص للوظيفة الشاغرة في الرسالة، ثم قم بتحليل المعلومات الموجودة في الرسالة على التوالي. أولاً، قم بالتحليل في السطر 83 للحصول على عنوان المرسل. سيتم استخدام هذه المعلمة لعمليات التحقق من الأذونات اللاحقة هنا ينتمي إلى صيغة سكر أخرى. ولن أتوسع فيه هنا. بعد ذلك، يتم تحليل بتات إشارة العملية، ثم تتم معالجة الطلبات المقابلة وفقًا لبتات إشارة مختلفة. من بينها، يتم استدعاء الوظائف المذكورة أعلاه على التوالي وفقا لمنطق معين. على سبيل المثال، يمكنك الرد على طلب لمعلمة حقوق الملكية، أو إنشاء nft جديد وزيادة الفهرس العالمي.
تتوافق نقطة المعرفة التالية مع السطر 108. أعتقد أنه يمكنك أيضًا معرفة منطق معالجة هذه الوظيفة عن طريق تسميتها، على غرار الدالة المطلوبة في Solidity، يتم طرح الاستثناءات في Func من خلال المعيار دالة throw_unless، معلمة الإدخال الأولى هي رمز الخطأ، والمعلمة الثانية هي التحقق من القيمة المنطقية للبت. في هذا السطر، يتم استخدامequal_slices لتحديد ما إذا كان عنوان المرسل الذي تم تحليله أعلاه يساوي عنوان المالك للتخزين المستمر للعقد، ويتم إصدار حكم الإذن.
أخيرًا، من أجل إنشاء بنية الكود أكثر وضوحًا، ابدأ هناك سلسلة من الوظائف المساعدة للمساعدة في الحصول على معلومات ثابتة، والتي لن يتم تقديمها هنا. يمكن للمطورين الرجوع إلى هذا الهيكل لتطوير عقودهم الذكية.
يعد تطوير التطبيقات اللامركزية في نظام TON البيئي أمرًا مثيرًا للاهتمام حقًا يختلف كثيرًا عن نموذج تطوير EVM، لذا سأقدم كيفية تطوير DApp في TON Chain من خلال سلسلة من المقالات. ص>