البرمجة الموجهة للعقد - الجزء 2
هذا هو الجزء الثاني من البرنامج التعليمي الموجه نحو العقد.هنا سوف ننظر في الشروط بعد الوصلات وبعض الوظائف أكثر تعقيدًا من تلك الموجودة في المنشور السابق.
ملاحظة.كما هو الحال في المنشور الأول ، هذه مجرد أمثلة قليلة على كيفية تطبيق بعض التقنيات البسيطة الموجهة نحو التعاقد في صلابة باستخدام المعدلات المخصصة.سنتحدث أكثر عن الفروق الدقيقة في المشاركات التالية.إنه أساسا للتجارب والبحث.
Postconsconditions
يمكن استخدام الشروط اللاحقة لضمان حدوث أشياء معينة بالفعل نتيجة لتنفيذ وظيفة معينة.عادةً ما تكون هذه تأكيدات حول بعض الحالة ، مثل رصيد المتصل أو حقل العقد.نحن لا نحد من أنواع الحالات التي يمكن (أو ينبغي) فحصها هنا.
مثال بسيط للغاية لشرط ما بعد هو:
|
|
لاحظ موضع _
داخل معدّل ما بعد الشرط ؛سيتم تنفيذ الوظيفة المعدلة * قبل القيام بالشيك ، على عكس المعدل المسبق للشرط حيث يتم الشيك أولاً.
من الممكن الجمع بين الشروط قبل وبعد.هنا مثال:
|
|
هذه ميزة آمنة للغاية. لا يتحقق فقط مما إذا كانت بيانات الإدخال صالحة (وهذا يعني في هذه الحالة أنه لا يتطابق مع البيانات المخزنة بالفعل) ، ولكن أيضًا يتحقق مما إذا كان متغير البيانات قد تم تغييره بالفعل قبل العودة. لن نذهب إلى وحدة اختبار هذا العقد كما فعلنا في الجزء 1 ، لأن الاختبارات ستكون هي نفسها.
ترتيب المعدلات
عند إضافة المعدلات إلى وظيفة ، من المهم جدًا طلبها بشكل صحيح. يجب إضافة المعدلات من اليسار إلى اليمين بالترتيب الذي سيتم تنفيذه. هذا يعني أنه إذا تم استخدام كل من الشروط المسبقة والشرافات البريدية ، فيجب علينا وضع الشروط المسبقة أولاً. لا يوجد فرق دلالي بين معدلات ما قبل وما بعد الولادة ، لذلك من الأفضل (في رأيي) استخدام استراتيجية تسمية جيدة. تتمثل إحدى الطرق في بادئة جميع أسماء المعدلات إما “قبل” أو “Post” ، على سبيل المثال. pre_data_is_zero
. لا توجد إرشادات في دليل أسلوب الصلابة الرسمي.
return
و `رمي"
قد يكون من الصعب تحديد كيفية الخروج من وظيفة إذا لم يتم استيفاء الشروط المسبقة أو الشروط البريدية. بالنظر إلى الطريقة التي تعمل بها الصلابة في الوقت الحالي ، فإن الأمر يتعلق بما إذا كنت تسمح “بالعودة” في المعدلات أو ينبغي أن “رمي”.
أنا شخصياً لست متأكدًا من أن هذا هو الحل الأفضل. أنا أميل دائمًا إلى الإقلاع عن التدخين. يعامل هذا النهج المعدلات على أنها تأكيدات تقليدية ، وإذا فشل التأكيد ، فهذا يعني أننا نضمن (نظريًا) أن تنفيذ الكود لن يكون له عواقب غير متوقعة. ما أعنيه “من الناحية النظرية” هو أنه صحيح طالما أن المعدلات مكتوبة بشكل صحيح وإضافتها إلى الوظائف بالطريقة الصحيحة ، وأن التنفيذ طبيعي (أي لا يتم استخدام مآثر EVM غريبة). يبدو أن هذه هي الطريقة الأكثر توجهاً نحو التعاقد لفعل الأشياء. الجانب السلبي هو أن “رمي” لا يسمح بأي شكل من أشكال الانتعاش عند الاتصال بوظائف ، لأنه لا توجد وسيلة لـ “الصيد” ، ولكن حتى لو استطعت ، لا يوجد أي أنواع أخطاء ، لكن كما أشرت في الجزء 1 - كما أنه لا يمكن إرجاع رموز الخطأ عند استخدام المعدلات ، لذلك لا يهم حقًا في الوقت الحالي.
فصل منطق الوظيفة عن الشروط
في بعض الأحيان ، قد يكون من الصعب معرفة ما إذا كان يجب وضع التعبير الشرطي داخل المعدل (كشرط مسبق أو ما بعد ذلك) أو يكون جزءًا من جسم الوظيفة نفسه. إليك عقد وظيفة أكثر تعقيدًا قليلاً من الجزء 1:
|
|
هنا نرى عددًا من الشرطية المستخدمة ، ولكن الأمر مختلف عن العقود التي نظرنا إليها حتى الآن في أن “Transfer” يمكن أن يفعل شيئين مختلفين تمامًا بناءً على حالة العقد - أحدهما هو نقل الأموال من واحدحساب لآخر ، والآخر هو تفريغ حساب المتصلين وإدراجهم السوداء.لذا ، كيف نحلل هذا؟
لنبدأ بالنظر إلى الشرطية.لدينا الثلاثة التالية:
blacklisted[msg.sender] == true
blacklisted[_dest] == false
balance[msg.sender] >= _amount
من بين هؤلاء ، أود أن أزعم أن “1” هو الشرط المسبق الوحيد.ويؤكد أن المتصل ليس مدرجًا في القائمة السوداء ، وإذا كان كذلك ، فلن يتم تشغيل بقية الجسم.لا ينبغي كسر الشرطين الآخرين ، لأنهما جزء من منطق الوظيفة.لا يهم إذا فشل واحد أو كليهما ؛ستظل الوظيفة تعمل على النحو المقصود.
ما لدينا بعد ذلك هو شرط مسبق ولا شروط بعد.مع المعدلات يجب أن تبدو مثل هذا:
|
|
تخيل الآن أننا نغير الوظيفة بحيث لا يتسبب التوازن المنخفض في إدراج المرسل في القائمة السوداء ، ولكن فقط منعهم من المعاملات (والذي يبدو بصراحة أكثر عقلانية).في هذه الحالة ، نغير التحقق من التوازن إلى شرط مسبق أيضًا.
(لاحظ أننا سنقوم أيضًا بتحديث الوثائق)
|
|
هذا يبدو كثيرًا ، لكن يمكننا فعل المزيد.لقد قمنا بالفعل بفصل منطق ضبط التوازن عن منطق القائمة السوداء ، مما يعني أنه يمكننا وضع هذا الرمز في وظيفة مختلفة ، وإضافة معدل at_east
إلى الوظيفة الجديدة بدلاً من ذلك.ستكون وظيفة ضبط التوازن خاصة ، بحيث يمكن فقط للوصول إلى وظيفة “النقل”.أيضًا ، لكي نكون أنيقًا للغاية ، يمكننا أن نخرج رمز القائمة السوداء أيضًا (الرمز الموجود داخل كتلة Else`).
|
|
لاحظ أنه يمكننا فقط استخدام مشغل ثلاثي في نص “النقل” في الوقت الحالي ، ولكن هذا يجعل القراءة من الصعب قراءتها ، لذلك لن نفعل ذلك.
لاحظ أيضًا أننا فصلنا الواجهة. وظيفة “النقل” لم تعد لديها فحص توازن ؛ بدلاً من ذلك ، تم نقله إلى وظيفة `__transfer" الخاصة. ومع ذلك ، إذا نظرنا إلى أقرب قليلاً ، يمكننا أن نرى أن هذا أمر منطقي بالفعل ، لأنه إذا كان الحساب المستهدف مدرجًا في القائمة السوداء ، فلن تستدعي وظيفة “النقل” منطق نقل الرصيد. هذه تفاصيل مهمة.
العقود والعقود الذكية
تستخدم هذه البرامج التعليمية نوعين مختلفين من العقود وينبغي أن تكون الاختلافات بينهما واضحة.
“العقد” هنا - من حيث البرمجة الموجهة للعقود - هو تعريف للوظائف ، أي ما تفعله الوظيفة ، والشروط التي يجب تلبية من أجل القيام بالوظيفة للقيام بعملها. إنه غير رسمي ، مما يعني أنه ليس لديه دعم اللغة الكاملة.
معيار التوازن في هذه الحالة هو شرط مسبق في تعريف العقد المعامل (غير الرسمي).
يتم استخدام المعدل AT_LEAST للتحقق من الرصيد في الكود.
وظيفة “النقل” هي المكان الذي يتم فيه تنفيذ الوظائف الموضحة في العقد. إنه جزء من “العقد الذكي” ، وهو الاسم المستخدم للرمز الذي يعمل في EVM (الجهاز الظاهري Ethereum).
وظيفة “النقل” هي نقطة دخول ، لكنها تشد بعض العمل إلى وظائف أخرى.
لاحظ أن “العقد” (في هذا السياق) ليس أيضًا JSON ABI من العقد الذكي ، كما أنه ليس JSON ABI وظيفة “Pass” ، على الرغم من أن JSON ABI جزء من تعريف العقد لأنه يحتوي على مواصفات للمدخلات والمخرجات وبعضها الآخر. أشياء. لا توجد طريقة في صلابة لتحديد هذه الأنواع من العقود رسميًا. يجب أن يتم الكثير من أعمال التحقق من الصحة المتعلقة بالعقد يدويًا ، ولكن لا يزال من الجيد العمل بهذه الطريقة لأنه (كما يشير Gavin) ، فإنه يجعل الكود أكثر أمانًا ويجعل التحقق من صحة واختباره أسهل.
أخيرًا ، لن أكون أيضًا في اختبار هذه العقود. المثال في الجزء 1 يكفي الآن. ربما سأضيف جزءًا مخصصًا لمجرد فرز الأساسيات.
استنتاج
يوضح هذا الجزء كيف يمكن إنشاء الشروط بعد المعدلات المخصصة وكيف يمكن تنظيم رمز أكثر تعقيدًا. كان الهدف من المثال المتقدم هو إظهار أنه لا يمكن تطبيق البرمجة الموجهة نحو التعاقد ببساطة عن طريق نقل البيانات الشرطية إلى معدلات مخصصة ، لكن هذا يتطلب بعض التفكير.
إذا أراد شخص ما معرفة المزيد عن البرمجة الموجه نحو العقد بشكل عام ، فيمكن العثور على وثيقة جيدة [هنا] (http://se.ethz.ch/~meyer/publications/computer/contract.pdf). يشرح العديد من المفاهيم وكيف يمكن تطبيقها.