المؤلف: جيمر سيرفيرا، مطور العقود الذكية لإيثريوم الترجمة: شان أوبا، Golden Finance< /p>
مقدمة
تقدم هذه المقالة سلسلة من المقالات التي توفر نظرة متعمقة على جهاز Ethereum الظاهري (EVM) وSolidity Assembly لتحسين وأمان العقود الذكية.
تعد آلة Ethereum الافتراضية (EVM) المكون الأساسي لشبكة Ethereum. EVM هو برنامج يسمح بنشر وتنفيذ العقود الذكية المكتوبة بلغات عالية المستوى مثل Solidity. بعد كتابة العقد، يتم تجميعه في كود ثانوي ونشره في EVM. يعمل EVM على كل عقدة على شبكة Ethereum.
Solidity Assembly هي لغة برمجة منخفضة المستوى تسمح للمطورين بكتابة التعليمات البرمجية على مستوى أقرب إلى EVM نفسها. فهو يوفر تحكمًا أكثر دقة في تنفيذ العقود الذكية، مما يسمح بالتحسينات والتخصيصات التي لا يمكن تحقيقها من خلال كود Solidity عالي المستوى وحده.
اللغة المستخدمة للتجميع المضمن في Solidity تسمى Yul. تعمل لغة البرمجة كوسيط للتجميع في رمز بايت EVM. وهي مصممة كلغة منخفضة المستوى تمكن المطورين من الحصول على تحكم أكثر دقة في تنفيذ العقود الذكية. يمكن استخدامه في الوضع المستقل أو التجميع المضمّن في Solidity. تم تصميم Yul كلغة منخفضة المستوى تعتمد على المكدس والتي تمكن المطورين من كتابة تعليمات برمجية أكثر كفاءة وفعالية. قبل شرح تجميع Solidity، نحتاج إلى فهم كيفية عمل مكونات EVM.
EVM هي آلة حالة شبه تورينج كاملة. في هذه الحالة، يعني المصطلح"شبه" أن تنفيذ العملية يقتصر على عدد محدود من الخطوات الحسابية، اعتمادًا على كمية الغاز المتاحة لتنفيذ أي عقد ذكي معين. هذه هي الطريقة التي يتعامل بها Ethereum مع المشكلات والمواقف التي قد يتم فيها تنفيذ التنفيذ (بشكل ضار أو غير مقصود) إلى الأبد. وهذا يتجنب الشلل الكامل لمنصة Ethereum.
الغاز هو مفهوم يقيس مقدار العمليات الحسابية المطلوبة لإكمال المعاملة في Ethereum. يتم دفع تكاليف المعاملة بالأثير وترتبط بسعر الغاز والغاز. هدفنا في هذه العملية هو معرفة كيفية تقليل إجمالي كمية الغاز المستهلكة دون المساس بالأمن.
مشكلات تحسين التعليمات البرمجية
التجميع المضمن هو وسيلة للوصول إلى EVM على مستوى أقل طريقة. إنه يتجاوز العديد من ميزات الأمان المهمة وفحوصات Solidity. الاستخدام السليم للتجميع المضمن يمكن أن يقلل بشكل كبير من تكاليف التنفيذ. ومع ذلك، يجب عليك استخدامه فقط للمهام التي تتطلب ذلك، وفقط إذا كنت تعرف ما تفعله. يمكن أن يؤدي استخدام التجميع المضمّن لتحسين التعليمات البرمجية الخاصة بك إلى ظهور مشكلات أمنية جديدة في التعليمات البرمجية الخاصة بك. لإتقان التجميع المضمن، نحتاج إلى فهم كيفية عمل EVM ومكوناته.
في EVM، يتعين عليك الدفع في كل مرة تصل فيها إلى أي متغير مخزن للمرة الأولى. وهذا ما يسمى "cold" الوصول والتكاليف 2100 غاز. يُطلق على الوصول الثاني أو المتتالي اسم الوصول "الساخن" ويكلف 100 غاز.
الكود التالي هو مثال لكيفية استخدام Yul لتحسين الكود الخاص بنا. تقوم الوظيفة SetData1 بتعيين قيمة جديدة لقيمة المتغير العام بالطريقة التقليدية باستخدام Solidity. أول مرة نخصص هذه القيمة الجديدة تكلف 22514 غاز. والثاني يكلف أقل بكثير، 5414 غاز.
مقدمة
تقدم هذه المقالة سلسلة من المقالات التي تستكشف بعمق آلة Ethereum الافتراضية ( EVM)) وSolidity Assembly لتحسين وأمان العقود الذكية.
تعد آلة Ethereum الافتراضية (EVM) المكون الأساسي لشبكة Ethereum. EVM هو برنامج يسمح بنشر وتنفيذ العقود الذكية المكتوبة بلغات عالية المستوى مثل Solidity. بعد كتابة العقد، يتم تجميعه في كود ثانوي ونشره في EVM. يعمل EVM على كل عقدة على شبكة Ethereum.
Solidity Assembly هي لغة برمجة منخفضة المستوى تسمح للمطورين بكتابة التعليمات البرمجية على مستوى أقرب إلى EVM نفسها. فهو يوفر تحكمًا أكثر دقة في تنفيذ العقود الذكية، مما يسمح بالتحسينات والتخصيصات التي لا يمكن تحقيقها من خلال كود Solidity عالي المستوى وحده.
اللغة المستخدمة للتجميع المضمن في Solidity تسمى Yul. تعمل لغة البرمجة كوسيط للتجميع في رمز بايت EVM. وهي مصممة كلغة منخفضة المستوى تمكن المطورين من الحصول على تحكم أكثر دقة في تنفيذ العقود الذكية. يمكن استخدامه في الوضع المستقل أو التجميع المضمّن في Solidity. تم تصميم Yul كلغة منخفضة المستوى تعتمد على المكدس والتي تمكن المطورين من كتابة تعليمات برمجية أكثر كفاءة وفعالية. قبل شرح تجميع Solidity، نحتاج إلى فهم كيفية عمل مكونات EVM.
EVM هي آلة حالة شبه تورينج كاملة. في هذه الحالة، يعني مصطلح "شبه" أن تنفيذ العملية يقتصر على عدد محدود من الخطوات الحسابية، اعتمادًا على كمية الغاز المتاحة لأي تنفيذ لعقد ذكي معين. هذه هي الطريقة التي يتعامل بها Ethereum مع المشكلات والمواقف التي قد يتم فيها تنفيذ التنفيذ (بشكل ضار أو غير مقصود) إلى الأبد. وهذا يتجنب الشلل الكامل لمنصة Ethereum.
الغاز هو مفهوم يقيس مقدار العمليات الحسابية المطلوبة لإكمال المعاملة في Ethereum. يتم دفع تكاليف المعاملة بالأثير وترتبط بسعر الغاز والغاز. هدفنا في هذه العملية هو معرفة كيفية تقليل إجمالي كمية الغاز الطبيعي المستهلك دون المساس بالسلامة.
مشكلات تحسين التعليمات البرمجية
التجميع المضمن هو وسيلة للوصول إلى EVM على مستوى أقل طريقة. إنه يتجاوز العديد من ميزات الأمان المهمة وفحوصات Solidity. الاستخدام السليم للتجميع المضمن يمكن أن يقلل بشكل كبير من تكاليف التنفيذ. ومع ذلك، يجب عليك استخدامه فقط للمهام التي تتطلب ذلك، وفقط إذا كنت تعرف ما تفعله. يمكن أن يؤدي استخدام التجميع المضمّن لتحسين التعليمات البرمجية الخاصة بك إلى ظهور مشكلات أمنية جديدة في التعليمات البرمجية الخاصة بك. لإتقان التجميع المضمن، نحتاج إلى فهم كيفية عمل EVM ومكوناته.
في EVM، يتعين عليك الدفع في كل مرة تصل فيها إلى أي متغير مخزن للمرة الأولى. وهذا ما يسمى "cold" الوصول والتكاليف 2100 غاز. تسمى الزيارة الثانية أو المتتالية بزيارة "ساخنة" وتكلف 100 بنزين.
الكود التالي هو مثال لكيفية استخدام Yul لتحسين الكود الخاص بنا. تقوم الوظيفة SetData1 بتعيين قيمة جديدة لقيمة المتغير العام بالطريقة التقليدية باستخدام Solidity. أول مرة نخصص هذه القيمة الجديدة تكلف 22514 غاز. والثاني يكلف أقل بكثير أي 5414 غاز.
p> p>
الوظيفة setData2 تنفذ التجميع المضمّن. يتم تمييز كتل التجميع المضمنة بالتجميع { … }، حيث يكون الرمز الموجود داخل الأقواس المتعرجة هو رمز لغة Yul. ليست هناك حاجة لمعرفة الكود المصدري في هذه المرحلة، فقط تذكر أن البرنامج يصل إلى مساحة التخزين بمستوى أقل. وبالتالي فإن تكاليف التنفيذ ستكون أقل.
في مثالنا، تعديل القيمة لأول مرة سيكلف 22484 غاز. عدة مرات متتالية كانت التكلفة 5384 غاز. قد لا يبدو الفرق كبيرًا، لكن يجب أن نأخذ في الاعتبار أن هذا الكود قد يتم تنفيذه آلاف المرات.
p> p>
لماذا يعتبر التخزين باهظ الثمن؟ تذكر أننا في عالم لا مركزي حيث لا يتم تخزين البيانات في مكان واحد فقط ولكن على عشرات الآلاف من العقد. ويجب أيضًا أن يكون متاحًا بسهولة لكل عقدة في الشبكة إذا كانت المعاملات المستقبلية تحتاج إلى الوصول إليه أو تغييره. التكلفة الإجمالية لهذه البيانات تساوي مجموع مساحة التخزين التي تستهلكها ومقدار العمليات الحسابية المطلوبة لتوليدها عبر الشبكة.
مكدس EVM والتخزين والذاكرة
EVM هو نظام قائم على المكدس جهاز يعمل على بنية بيانات تسمى المكدس، الذي يحمل القيم وينفذ العمليات. لدى EVM مجموعة التعليمات الخاصة به (تسمى رموز التشغيل) التي يتم استخدامها لأداء مهام مثل قراءة وكتابة التخزين، واستدعاء العقود الأخرى، وتنفيذ العمليات الحسابية. تعمل المكدس بطريقة ما يدخل أولاً يخرج أولاً (LIFO)، انظر الشكل 1، مما يعني أن العنصر الذي تم إدراجه مؤخرًا يتم تخزينه في الجزء العلوي من المكدس وهو أول عنصر يتم إزالته.
p> p>
عند تنفيذ عقد ذكي، يقوم EVM بإنشاء سياق تنفيذ يحتوي على هياكل بيانات مختلفة ومتغيرات الحالة. بعد اكتمال التنفيذ، يتم التخلص من سياق التنفيذ استعدادًا للعقد التالي. أثناء التنفيذ، يحتفظ EVM بذاكرة مؤقتة لا تستمر بين المعاملات. ينفذ EVM آلة مكدس بعمق 1024 إدخالاً. كل عنصر عبارة عن كلمة 256 بت، وقد تم اختيار هذا الحجم لتسهيل استخدام تجزئة 256 بت وتشفير المنحنى الإهليلجي.
يحتوي EVM على المكونات التالية، انظر الشكل 2:
Stack: مكدس EVM عبارة عن بنية بيانات تعمل بطريقة آخر ما يدخل أولاً (LIFO) وتستخدم لتخزين القيم المؤقتة أثناء تنفيذ العقد الذكي.
التخزين: تخزين دائم، جزء من حالة Ethereum، تمت تهيئته إلى الصفر في المرة الأولى فقط.
الذاكرة: مصفوفة بايت متطايرة ذات حجم ديناميكي تستخدم لتخزين البيانات الوسيطة أثناء تنفيذ العقد. في كل مرة يتم إنشاء سياق تنفيذ جديد، تتم تهيئة الذاكرة إلى الصفر.
بيانات الاتصال: وهي أيضًا منطقة تخزين بيانات متطايرة، تشبه الذاكرة. ومع ذلك فإنه يخزن بيانات غير قابلة للتغيير. وهو مصمم للاحتفاظ بالبيانات المرسلة كجزء من معاملات العقود الذكية.
عداد البرنامج: يشير عداد البرنامج (الكمبيوتر الشخصي) إلى التعليمات التالية التي سيتم تنفيذها بواسطة EVM. عادةً ما يزيد جهاز الكمبيوتر بمقدار بايت واحد بعد تنفيذ التعليمات.
ذاكرة القراءة فقط الافتراضية: يتم تخزين العقود الذكية كرمز ثانوي في هذه المنطقة. ROM الظاهري للقراءة فقط.
مكدس EVM
في هذه البنية، تعليمات يتم الاحتفاظ بالبرنامج والبيانات في الذاكرة، ويتم التحكم في تنفيذ البرنامج بواسطة مؤشر المكدس الذي يشير إلى أعلى المكدس. يتتبع مؤشر المكدس المكان الذي سيتم فيه حفظ أو استرداد القيمة أو التعليمات التالية على المكدس. عند تشغيل البرنامج، فإنه يضيف قيمًا إلى المكدس وينفذ العمليات على القيم الموجودة بالفعل. عندما يريد الكود إضافة رقمين، فإنه يدفع الأرقام إلى المكدس ثم ينفذ عملية الإضافة على القيمتين العلويتين. ثم يتم إرجاع النتيجة إلى المكدس.
p> p>
إحدى أهم ميزات البنية القائمة على المكدس هي أنها تسمح بتنفيذ العمليات بشكل بسيط وفعال للغاية. نظرًا لأن المكدس عبارة عن بنية بيانات LIFO، فيمكن معالجة البيانات والتعليمات بسهولة وسرعة.
يمتلك EVM مجموعة تعليمات خاصة به تسمى أكواد التشغيل. تُستخدم أكواد التشغيل لأداء مهام مثل قراءة وكتابة التخزين واستدعاء العقود الأخرى وإجراء العمليات الحسابية. توفر مجموعة تعليمات EVM معظم العمليات التي قد تتوقعها، بما في ذلك:
عمليات المكدس: POP، PUSH، DUP، SWAP
الحساب/المقارنة/البت: ADD، SUB، GT، LT، AND، OR p>
البيئة: المتصل، قيمة المكالمة، الرقم
عمليات الذاكرة: MLOAD, MSTORE, MSTORE8, MSIZE
عمليات التخزين: SLOAD, SSTORE
أكواد التشغيل ذات الصلة بعداد البرنامج: JUMP، JUMPI، PC، JUMPDEST
إيقاف رموز التشغيل: STOP، RETURN، REVERT، INVALID، SELFDESTRUCT
تخزين EVM
تخزين EVM عبارة عن مساحة غير متطايرة تقوم بتخزين أزواج قيمة المفتاح 256 بت –> 256 بت. إجمالي عدد فتحات التخزين في العقد هو 2²⁵⁶، وهو عدد كبير جدًا من الفتحات. كل عقد ذكي على blockchain له مساحة تخزين خاصة به.
أثناء استدعاء الوظيفة، يقوم بتخزين البيانات التي يجب تذكرها بين استدعاءات الوظائف. يتم استخدامه لتخزين المتغيرات وهياكل البيانات التي يجب أن تكون متاحة حتى بعد انتهاء تنفيذ العقد الذكي.
p> p>
رموز التشغيل للوصول إلى التخزين هي: SLOAD وSSTORE
التخزين لهذا الحساب هو تخزين دائم للبيانات، يُستخدم فقط من خلال العقود الذكية. لن تحتوي الحسابات المملوكة خارجيًا (EOA) دائمًا على أي رمز ومساحة تخزين فارغة.
ذاكرة EVM
الذاكرة هي ذاكرة متطايرة في البنية، وبياناتها موجودة في المنطقة لا يوجد استمرار في blockchain. الذاكرة عبارة عن بنية بيانات وصول عشوائي تقوم بتخزين البيانات المؤقتة أثناء تنفيذ العقد الذكي.
p> p>
تنقسم الذاكرة إلى أربعة أجزاء: فتحتان للمساحة المؤقتة، وفتحة واحدة لمؤشرات الذاكرة المجانية، و0 فتحة وفتحة واحدة تشير إلى الذاكرة الحرة المتوفرة . سيتم استخدام أول 64 بايت من المساحة بواسطة طرق التجزئة، والتي تتطلب مساحة مؤقتة لتخزين المخرجات المتوسطة قبل إرجاع الإخراج النهائي في النهاية.
مؤشر الذاكرة الحرة هو مجرد مؤشر لبداية الذاكرة الحرة. فهو يضمن أن العقد الذكي يتتبع مواقع الذاكرة التي تمت كتابتها والمواقع التي لا تزال متاحة. يمنع هذا العقد من الكتابة فوق بعض الذاكرة التي تم تخصيصها لمتغير آخر. يوضح الشكل 6 كيفية تقسيم الذاكرة:
تستخدم الذاكرة لتخزين المتغيرات وهياكل البيانات التي لا تحتاج إلى تخزينها في الذاكرة. يمكن تعديل حجم الذاكرة أثناء تنفيذ العقد الذكي، لكن الوصول إليها يكون أبطأ وأكثر تكلفة من المكدس.
ضع في اعتبارك أن الذاكرة تمت تهيئتها صفرًا، وأن رموز التشغيل المستخدمة للوصول إلى الذاكرة هي: MLOAD، MSTORE، MSTORE8
الملخص
في هذه المقالة، نراجع بعض المفاهيم الأساسية المتعلقة بجهاز Ethereum الظاهري (EVM). يتطلب تنفيذ كود التجميع المضمن فهمًا عميقًا لـ EVM. وذلك لأننا نتفاعل مع بعض مكونات EVM. في الدروس القادمة، سنقوم بتحليل عناصر EVM الأخرى بمزيد من التفصيل، مثل: التخزين والذاكرة وبيانات الاتصال. بالإضافة إلى ذلك، نقوم بمراجعة مفاهيم مهمة مثل الرمز الثانوي والغاز والواجهة الثنائية للتطبيقات (ABI). أخيرًا، سنناقش كيفية عمل أكواد التشغيل والمزيد من أمثلة التجميع المضمنة لتحسين تنفيذ العقود الذكية بأمان. ص>