أمان العقد الذكي
آخر تحديث للصفحة: 26 فبراير 2026
العقود الذكية مرنة للغاية، وقادرة على التحكم في كميات كبيرة من القيمة والبيانات، مع تشغيل منطق ثابت يعتمد على الكود المنشور على blockchain. وقد أدى ذلك إلى إنشاء نظام بيئي نابض بالحياة من التطبيقات غير الموثوقة واللامركزية التي توفر العديد من المزايا مقارنة بالأنظمة القديمة. كما أنها تمثل فرصًا للمهاجمين الذين يتطلعون إلى الربح من خلال استغلال نقاط الضعف في العقود الذكية.
تزيد سلاسل الكتل العامة، مثل إيثريوم، من تعقيد مسألة تأمين العقود الذكية. عادةً لا يمكن تغيير كود العقد الذي تم نشره لتصحيح العيوب الأمنية، في حين أن الأصول المسروقة من العقود الذكية يصعب للغاية تتبعها وغير قابلة للاسترداد في الغالب بسبب عدم قابليتها للتغيير.
على الرغم من اختلاف الأرقام، فمن المقدر أن المبلغ الإجمالي للقيمة المسروقة أو المفقودة بسبب العيوب الأمنية في العقود الذكية يزيد بسهولة عن مليار دولار. وهذا يشمل الحوادث البارزة، مثل اختراق داو (opens in a new tab) (تمت سرقة 3.6 مليون ETH، بقيمة تزيد عن مليار دولار بأسعار اليوم)، واختراق محفظة باريتي متعددة التوقيع (opens in a new tab) (خسارة 30 مليون دولار للمخترقين)، ومشكلة محفظة باريتي المجمدة (opens in a new tab) (تم قفل أكثر من 300 مليون دولار من ETH إلى الأبد).
تحتم المشكلات المذكورة أعلاه على المطورين استثمار الجهود في بناء عقود ذكية آمنة وقوية ومرنة. يعد أمان العقود الذكية عملاً جادًا، ومن الأفضل لكل مطور أن يتعلمه. سيغطي هذا الدليل الاعتبارات الأمنية لمطوري إيثريوم ويستكشف الموارد لتحسين أمان العقود الذكية.
المتطلبات الأساسية
تأكد من أنك على دراية بـ أساسيات تطوير العقود الذكية قبل التعامل مع الأمن.
إرشادات لبناء عقود إيثريوم ذكية آمنة
١. تصميم ضوابط وصول مناسبة
في العقود الذكية، يمكن استدعاء الوظائف المميزة بـ public أو external من قبل أي حسابات مملوكة خارجيًا (EOAs) أو حسابات عقود. يعد تحديد الرؤية العامة للوظائف أمرًا ضروريًا إذا كنت تريد أن يتفاعل الآخرون مع عقدك. لكن الوظائف المميزة بـ private لا يمكن استدعاؤها إلا من خلال الوظائف الموجودة داخل العقد الذكي، وليس من الحسابات الخارجية. إن منح كل مشارك في الشبكة إمكانية الوصول إلى وظائف العقد يمكن أن يسبب مشاكل، خاصة إذا كان ذلك يعني أنه يمكن لأي شخص إجراء عمليات حساسة (على سبيل المثال، سك الرموز المميزة الجديدة).
لمنع الاستخدام غير المصرح به لوظائف العقود الذكية، من الضروري تنفيذ ضوابط الوصول الآمن. تعمل آليات التحكم في الوصول على تقييد القدرة على استخدام وظائف معينة في العقد الذكي على الكيانات المعتمدة، مثل الحسابات المسؤولة عن إدارة العقد. يعد نمط Ownable والتحكم القائم على الأدوار نمطين مفيدين لتنفيذ التحكم في الوصول في العقود الذكية:
نمط Ownable
في النمط القابل للتملك، يتم تعيين عنوان باعتباره "مالك" العقد أثناء عملية إنشاء العقد. يتم تعيين مُعدِّل OnlyOwner للوظائف المحمية، مما يضمن أن العقد يصادق على هوية عنوان المتصل قبل تنفيذ الوظيفة. يتم دائمًا إرجاع المكالمات إلى الوظائف المحمية من عناوين أخرى بخلاف مالك العقد، مما يمنع الوصول غير المرغوب فيه.
التحكم في الوصول القائم على الأدوار
تسجيل عنوان واحد كـ Owner في عقد ذكي يمثل خطر المركزية ونقطة فشل واحدة. إذا تم اختراق مفاتيح حساب المالك، فيمكن للمهاجمين مهاجمة العقد المملوك. ولهذا السبب قد يكون استخدام نمط التحكم في الوصول المستند إلى الدور مع حسابات إدارية متعددة خيارًا أفضل.
في التحكم في الوصول المستند إلى الدور، يتم توزيع الوصول إلى الوظائف الحساسة بين مجموعة من المشاركين الموثوق بهم. على سبيل المثال، قد يكون أحد الحسابات مسؤولاً عن سك العملات، بينما يقوم حساب آخر بإجراء ترقيات أو إيقاف العقد مؤقتًا. تؤدي لامركزية التحكم في الوصول بهذه الطريقة إلى التخلص من نقاط الفشل الفردية وتقليل افتراضات الثقة للمستخدمين.
استخدام محافظ متعددة التوقيع
هناك نهج آخر لتنفيذ التحكم الآمن في الوصول وهو استخدام حساب متعدد التوقيع لإدارة العقد. على عكس EOA العادي، فإن الحسابات متعددة التوقيع مملوكة لكيانات متعددة وتتطلب توقيعات من الحد الأدنى لعدد الحسابات - على سبيل المثال 3 من 5 - لتنفيذ المعاملات.
يقدم استخدام multisig للتحكم في الوصول طبقة إضافية من الأمان نظرًا لأن الإجراءات المتعلقة بالعقد المستهدف تتطلب موافقة من أطراف متعددة. يعد هذا مفيدًا بشكل خاص إذا كان استخدام النمط القابل للامتلاك ضروريًا، لأنه يجعل من الصعب على المهاجم أو المطلعين المارقين التعامل مع وظائف العقد الحساسة لأغراض ضارة.
٢. استخدم عبارات ()require و ()assert و ()revert لحماية عمليات العقد
كما ذكرنا سابقًا، يمكن لأي شخص استدعاء الوظائف العامة في عقدك الذكي بمجرد نشره على سلسلة كتلة. نظرًا لأنه لا يمكنك معرفة كيفية تفاعل الحسابات الخارجية مع العقد مسبقًا، فمن المثالي تنفيذ إجراءات وقائية داخلية ضد العمليات التي بها مشكلات قبل النشر. يمكنك فرض السلوك الصحيح في العقود الذكية باستخدام عبارات require() و assert() و revert() لتشغيل الاستثناءات وإلغاء تغييرات الحالة إذا فشل التنفيذ في تلبية متطلبات معينة.
require(): تُعرَّف require في بداية الوظائف وتضمن استيفاء الشروط المحددة مسبقًا قبل تنفيذ الوظيفة المستدعاة. يمكن استخدام عبارة require للتحقق من صحة مدخلات المستخدم، أو فحص متغيرات الحالة، أو المصادقة على هوية الحساب المتصل قبل المتابعة في الوظيفة.
assert(): تُستخدم assert() لاكتشاف الأخطاء الداخلية والتحقق من انتهاكات "invariants" (الثوابت) في الكود الخاص بك. الثابت هو تأكيد منطقي حول حالة العقد والذي يجب أن ينطبق على جميع عمليات تنفيذ الوظائف مثال ثابت هو الحد الأقصى لإجمالي العرض أو الرصيد لعقد الرمز المميز. يضمن استخدام assert() عدم وصول عقدك أبدًا إلى حالة ضعيفة، وإذا وصل، يتم التراجع عن جميع التغييرات في متغيرات الحالة.
revert(): يمكن استخدام revert() في جملة if-else التي تطلق استثناءً إذا لم يتم استيفاء الشرط المطلوب. يستخدم نموذج العقد أدناه revert() لحماية تنفيذ الوظائف:
1pragma solidity ^0.8.4;23contract VendingMachine {4 address owner;5 error Unauthorized();6 function buy(uint amount) public payable {7 if (amount > msg.value / 2 ether)8 revert("Not enough Ether provided.");9 // قم بتنفيذ عملية الشراء.10 }11 function withdraw() public {12 if (msg.sender != owner)13 revert Unauthorized();1415 payable(msg.sender).transfer(address(this).balance);16 }17}إظهار الكل3. اختبار العقود الذكية والتحقق من صحة الكود
إن ثبات الكود الذي يعمل في آلة إيثريوم الافتراضية يعني أن العقود الذكية تتطلب مستوى أعلى من تقييم الجودة خلال مرحلة التطوير. سيؤدي اختبار العقد الخاص بك على نطاق واسع ومراقبته بحثًا عن أي نتائج غير متوقعة إلى تحسين الأمان بشكل كبير وحماية المستخدمين على المدى الطويل.
الطريقة المعتادة هي كتابة اختبارات الوحدات الصغيرة باستخدام بيانات وهمية من المتوقع أن يتلقاها العقد من المستخدمين. اختبار الوحدة جيد لاختبار وظائف معينة وضمان عمل العقد الذكي كما هو متوقع.
لسوء الحظ، يعد اختبار الوحدة فعالاً إلى الحد الأدنى لتحسين أمان العقود الذكية عند استخدامه بشكل منفصل. قد يثبت اختبار الوحدة أن الوظيفة يتم تنفيذها بشكل صحيح للبيانات الوهمية، ولكن اختبارات الوحدة تكون فعالة فقط مثل الاختبارات المكتوبة. وهذا يجعل من الصعب اكتشاف حالات الحافة المفقودة ونقاط الضعف التي قد تؤدي إلى انتهاك سلامة عقدك الذكي.
النهج الأفضل هو الجمع بين اختبار الوحدة والاختبار القائم على الخصائص الذي يتم إجراؤه باستخدام التحليل الثابت والديناميكي. يعتمد التحليل الثابت على تمثيلات منخفضة المستوى، مثل الرسوم البيانية لتدفق التحكم (opens in a new tab) وأشجار بناء الجملة المجردة (opens in a new tab) لتحليل حالات البرنامج ومسارات التنفيذ التي يمكن الوصول إليها. في الوقت نفسه، تقوم تقنيات التحليل الديناميكي، مثل اختبار التشويش (fuzzing) للعقود الذكية (opens in a new tab)، بتنفيذ كود العقد بقيم إدخال عشوائية للكشف عن العمليات التي تنتهك خصائص الأمان.
التحقق الرسمي هو أسلوب آخر للتحقق من الخصائص الأمنية في العقود الذكية. على عكس الاختبارات المنتظمة، يمكن للتحقق الرسمي أن يثبت بشكل قاطع عدم وجود أخطاء في العقد الذكي. ويتم تحقيق ذلك من خلال إنشاء مواصفات رسمية تلتقط الخصائص الأمنية المطلوبة وإثبات أن النموذج الرسمي للعقود يلتزم بهذه المواصفات.
4. اطلب مراجعة مستقلة للكود الخاص بك
بعد اختبار العقد الخاص بك، من الجيد أن تطلب من الآخرين التحقق من رمز المصدر بحثًا عن أي مشكلات أمنية. لن يكشف الاختبار عن كل خلل في العقد الذكي، ولكن الحصول على مراجعة مستقلة يزيد من إمكانية اكتشاف نقاط الضعف.
عمليات التدقيق
يعد التكليف بمراجعة العقود الذكية إحدى طرق إجراء مراجعة مستقلة للتعليمات البرمجية. يلعب المدققون دورًا مهمًا في ضمان أن العقود الذكية آمنة وخالية من عيوب الجودة وأخطاء التصميم.
ومع ذلك، يجب عليك تجنب التعامل مع عمليات التدقيق باعتبارها الحل السحري. لن تكتشف عمليات تدقيق العقود الذكية كل الأخطاء، وهي مصممة في الغالب لتوفير جولة إضافية من المراجعات، والتي يمكن أن تساعد في اكتشاف المشكلات التي غاب عنها المطورون أثناء التطوير والاختبار الأولي. يجب عليك أيضًا اتباع أفضل الممارسات للعمل مع المدققين، مثل توثيق التعليمات البرمجية بشكل صحيح وإضافة التعليقات المضمنة، لتحقيق أقصى استفادة من تدقيق العقود الذكية.
- نصائح وحيل لتدقيق العقود الذكية (opens in a new tab) - @tinchoabbate
- حقق أقصى استفادة من التدقيق الخاص بك (opens in a new tab) - Inference
مكافآت الأخطاء
يعد إعداد برنامج مكافأة الأخطاء طريقة أخرى لتنفيذ مراجعات التعليمات البرمجية الخارجية. مكافأة الأخطاء هي مكافأة مالية تُمنح للأفراد (عادةً قراصنة القبعة البيضاء) الذين يكتشفون نقاط الضعف في أحد التطبيقات.
عند استخدامها بشكل صحيح، تمنح مكافآت الأخطاء أعضاء مجتمع المتسللين حافزًا لفحص التعليمات البرمجية الخاصة بك بحثًا عن العيوب الخطيرة. مثال من واقع الحياة هو "ثغرة الأموال اللانهائية" التي كانت ستسمح لمهاجم بإنشاء كمية غير محدودة من الإيثر على أوبتيميزم (opens in a new tab)، وهو بروتوكول الطبقة الثانية يعمل على إيثريوم. لحسن الحظ، اكتشف مخترق ذو قبعة بيضاء (whitehat) الثغرة (opens in a new tab) وأبلغ الفريق، وحصل على مكافأة كبيرة في هذه العملية (opens in a new tab).
تتمثل الإستراتيجية المفيدة في تحديد دفع تعويضات برنامج مكافأة الأخطاء بما يتناسب مع حجم الأموال المعرضة للخطر. يوفر هذا النهج، الذي يوصف بأنه "مكافأة أخطاء التوسع (opens in a new tab)"، حوافز مالية للأفراد للكشف عن نقاط الضعف بمسؤولية بدلاً من استغلالها.
5. اتبع أفضل الممارسات أثناء تطوير العقود الذكية
إن وجود عمليات التدقيق ومكافآت الأخطاء لا يعفي مسؤوليتك عن كتابة تعليمات برمجية عالية الجودة. يبدأ الأمان الجيد للعقود الذكية باتباع عمليات التصميم والتطوير المناسبة:
-
قم بتخزين جميع التعليمات البرمجية في نظام التحكم في الإصدار، مثل git
-
قم بإجراء جميع تعديلات التعليمات البرمجية عبر طلبات السحب
-
تأكد من أن طلبات السحب تحتوي على مراجع مستقل واحد على الأقل - إذا كنت تعمل بمفردك على مشروع ما، ففكر في البحث عن مطورين آخرين ومراجعة أكواد التجارة
-
استخدم بيئة تطوير لاختبار العقود الذكية وتجميعها ونشرها
-
قم بتشغيل الكود الخاص بك من خلال أدوات تحليل الكود الأساسية، مثل Cyfrin Aderyn (opens in a new tab) و ميثريل و سليذر. من الناحية المثالية، يجب عليك القيام بذلك قبل دمج كل طلب سحب ومقارنة الاختلافات في المخرجات
-
تأكد من تجميع التعليمات البرمجية الخاصة بك دون أخطاء، وأن برنامج التحويل البرمجي سوليديتي لا يصدر أي تحذيرات
-
وثق الكود الخاص بك بشكل صحيح (باستخدام نات سبيك (opens in a new tab)) وصف تفاصيل بنية العقد بلغة سهلة الفهم. سيؤدي ذلك إلى تسهيل قيام الآخرين بتدقيق ومراجعة التعليمات البرمجية الخاصة بك.
6. تنفيذ خطط قوية للتعافي من الكوارث
يمكن لتصميم عناصر التحكم في الوصول الآمن، وتنفيذ معدّلات الوظائف، والاقتراحات الأخرى تحسين أمان العقود الذكية، ولكن لا يمكنها استبعاد احتمال حدوث عمليات استغلال ضارة. يتطلب بناء عقود ذكية آمنة "الاستعداد للفشل" ووضع خطة احتياطية للرد بفعالية على الهجمات. ستتضمن خطة التعافي من الكوارث المناسبة بعضًا أو كل المكونات التالية:
ترقيات العقود
في حين أن العقود الذكية لإيثريوم غير قابلة للتغيير بشكل افتراضي، فمن الممكن تحقيق درجة معينة من القابلية للتغيير باستخدام أنماط الترقية. تعد ترقية العقود ضرورية في الحالات التي يؤدي فيها وجود خلل خطير إلى جعل عقدك القديم غير قابل للاستخدام، كما أن نشر منطق جديد هو الخيار الأكثر جدوى.
تعمل آليات ترقية العقود بشكل مختلف، ولكن "نمط الوكيل" هو أحد الأساليب الأكثر شيوعًا لترقية العقود الذكية. تقسم أنماط الوكيل (Proxy patterns) (opens in a new tab) حالة التطبيق ومنطقه بين عقدين اثنين. العقد الأول (يسمى "عقد الوكيل") يخزن متغيرات الحالة (على سبيل المثال، أرصدة المستخدم)، في حين أن العقد الثاني (يسمى "العقد المنطقي") يحمل رمز تنفيذ وظائف العقد.
تتفاعل الحسابات مع عقد الوكيل (proxy)، الذي يرسل جميع استدعاءات الوظائف إلى عقد المنطق باستخدام الاستدعاء منخفض المستوى delegatecall() (opens in a new tab). على عكس استدعاء الرسائل العادي، يضمن delegatecall() أن الكود الذي يعمل على عنوان عقد المنطق يتم تنفيذه في سياق العقد المتصل. هذا يعني أن عقد المنطق سيكتب دائمًا إلى مساحة تخزين الوكيل (proxy) (بدلاً من مساحة التخزين الخاصة به) ويتم الحفاظ على القيم الأصلية لـ msg.sender و msg.value.
يتطلب تفويض الاستدعاءات للعقد المنطقي تخزين عنوانه في مخزن عقد الوكيل. ومن ثم، فإن ترقية منطق العقد هي مجرد مسألة نشر عقد منطقي آخر وتخزين العنوان الجديد في عقد الوكيل. نظرًا لأن الاستدعاءات اللاحقة لعقد الوكيل يتم توجيهها تلقائيًا إلى العقد المنطقي الجديد، فستكون قد قمت "بترقية" العقد دون تعديل الكود فعليًا.
التوقفات الطارئة
كما ذكرنا سابقًا، لا يمكن للتدقيق والاختبار الشامل اكتشاف جميع الأخطاء في العقد الذكي. إذا ظهرت ثغرة أمنية في التعليمات البرمجية الخاصة بك بعد النشر، فمن المستحيل تصحيحها حيث لا يمكنك تغيير التعليمات البرمجية التي تعمل على عنوان العقد. كما أن آليات الترقية (على سبيل المثال، أنماط الوكيل) قد تستغرق وقتًا للتنفيذ (غالبًا ما تتطلب موافقة من أطراف مختلفة)، مما يمنح المهاجمين مزيدًا من الوقت لإحداث المزيد من الضرر.
الخيار النووي هو تنفيذ وظيفة "التوقف في حالات الطوارئ" التي تمنع المكالمات إلى الوظائف الضعيفة في العقد. تشتمل محطات التوقف في حالات الطوارئ عادةً على المكونات التالية:
-
متغير منطقي عالمي يشير إلى ما إذا كان العقد الذكي في حالة توقف أم لا. يتم تعيين هذا المتغير إلى
falseعند إعداد العقد، ولكنه سيعود إلىtrueبمجرد إيقاف العقد. -
الوظائف التي تشير إلى المتغير المنطقي في تنفيذها. يمكن الوصول إلى هذه الوظائف عندما لا يتم إيقاف العقد الذكي، ولا يمكن الوصول إليها عند تشغيل ميزة التوقف في حالات الطوارئ.
-
كيان لديه حق الوصول إلى وظيفة التوقف في حالات الطوارئ، والتي تعيّن المتغير المنطقي إلى
true. لمنع الإجراءات الضارة، يمكن قصر استدعاءات هذه الوظيفة على عنوان موثوق به (على سبيل المثال، مالك العقد).
بمجرد أن يقوم العقد بتنشيط التوقف الطارئ، لن تكون بعض الوظائف قابلة للاستدعاء. يتم تحقيق ذلك عن طريق تغليف وظائف محددة في مُعدِّل يشير إلى المتغير العام. فيما يلي مثال (opens in a new tab) يصف تنفيذ هذا النمط في العقود:
1// لم يتم تدقيق هذا الكود بشكل احترافي ولا يقدم أي وعود حول السلامة أو الصحة. استخدمه على مسؤوليتك الخاصة.23contract EmergencyStop {45 bool isStopped = false;67 modifier stoppedInEmergency {8 require(!isStopped);9 _;10 }1112 modifier onlyWhenStopped {13 require(isStopped);14 _;15 }1617 modifier onlyAuthorized {18 // تحقق من صلاحية msg.sender هنا19 _;20 }2122 function stopContract() public onlyAuthorized {23 isStopped = true;24 }2526 function resumeContract() public onlyAuthorized {27 isStopped = false;28 }2930 function deposit() public payable stoppedInEmergency {31 // منطق الإيداع يحدث هنا32 }3334 function emergencyWithdraw() public onlyWhenStopped {35 // سحب الطوارئ يحدث هنا36 }37}إظهار الكليوضح هذا المثال الميزات الأساسية للتوقف في حالات الطوارئ:
-
isStoppedهو متغير منطقي (Boolean) قيمتهfalseفي البداية وtrueعندما يدخل العقد في وضع الطوارئ. -
يقوم مُعدِّلا الوظائف
onlyWhenStoppedوstoppedInEmergencyبالتحقق من متغيرisStopped. يُستخدمstoppedInEmergencyللتحكم في الوظائف التي يجب أن تكون غير قابلة للوصول عندما يكون العقد ضعيفًا (على سبيل المثال،deposit()). سيتم ببساطة إرجاع المكالمات إلى هذه الوظائف.
يُستخدم onlyWhenStopped للوظائف التي يجب أن تكون قابلة للاستدعاء أثناء حالة الطوارئ (على سبيل المثال، emergencyWithdraw()). يمكن أن تساعد مثل هذه الوظائف في حل الموقف، وبالتالي استبعادها من قائمة "الوظائف المقيدة".
يوفر استخدام وظيفة التوقف في حالات الطوارئ حلاً مؤقتًا فعالاً للتعامل مع نقاط الضعف الخطيرة في عقدك الذكي. ومع ذلك، فإنه يزيد من حاجة المستخدمين إلى الثقة في المطورين حتى لا يقوموا بتنشيطه لأسباب تتعلق بالخدمة الذاتية. ولتحقيق هذه الغاية، فإن اللامركزية في التحكم في التوقف الطارئ إما عن طريق إخضاعه لآلية التصويت على السلسلة، أو القفل الزمني، أو الموافقة من محفظة متعددة التوقيعات هي حلول ممكنة.
مراقبة الأحداث
الأحداث (opens in a new tab) تسمح لك بتتبع الاستدعاءات لوظائف العقود الذكية ومراقبة التغييرات في متغيرات الحالة. إنه مثالي لبرمجة عقدك الذكي لإصدار حدث عندما يتخذ أحد الأطراف إجراءً بالغ الأهمية للسلامة (على سبيل المثال، سحب الأموال).
يساعد تسجيل الأحداث ومراقبتها خارج السلسلة على توفير رؤى حول عمليات العقد ويساعد في اكتشاف الإجراءات الضارة بشكل أسرع. وهذا يعني أن فريقك يمكنه الاستجابة بشكل أسرع للاختراقات واتخاذ الإجراءات اللازمة للتخفيف من التأثير على المستخدمين، مثل إيقاف الوظائف مؤقتًا أو إجراء ترقية.
يمكنك أيضًا اختيار أداة مراقبة جاهزة لإعادة توجيه التنبيهات تلقائيًا عندما يتفاعل شخص ما مع عقودك. ستسمح لك هذه الأدوات بإنشاء تنبيهات مخصصة بناءً على مشغلات مختلفة، مثل حجم المعاملة، أو تكرار استدعاءات الوظائف، أو الوظائف المحددة المعنية. على سبيل المثال، يمكنك برمجة تنبيه يأتي عندما يتجاوز المبلغ المسحوب في معاملة واحدة حدًا معينًا.
7. تصميم أنظمة حوكمة آمنة
قد ترغب في تحقيق اللامركزية في تطبيقك من خلال تسليم التحكم في العقود الذكية الأساسية إلى أفراد المجتمع. في هذه الحالة، سيتضمن نظام العقد الذكي وحدة حوكمة - وهي آلية تسمح لأعضاء المجتمع بالموافقة على الإجراءات الإدارية عبر نظام حوكمة على السلسلة. على سبيل المثال، قد يتم التصويت على اقتراح لترقية عقد الوكيل إلى تنفيذ جديد من قبل حاملي الرمز المميز.
يمكن أن تكون الإدارة اللامركزية مفيدة، خاصة لأنها تتوافق مع مصالح المطورين والمستخدمين النهائيين. ومع ذلك، فإن آليات حوكمة العقود الذكية قد تؤدي إلى مخاطر جديدة إذا تم تنفيذها بشكل غير صحيح. سيناريو محتمل هو أن يكتسب مهاجم قوة تصويت هائلة (تقاس بعدد الرموز المحتفظ بها) عن طريق أخذ قرض سريع ويمرر اقتراحًا خبيثًا.
إحدى طرق منع المشاكل المتعلقة بالحوكمة على السلسلة (onchain) هي استخدام قفل زمني (timelock) (opens in a new tab). يمنع القفل الزمني العقد الذكي من تنفيذ إجراءات معينة حتى مرور فترة زمنية محددة. وتشمل الاستراتيجيات الأخرى تعيين "وزن التصويت" لكل رمز بناءً على المدة التي تم قفله فيها، أو قياس قوة التصويت لعنوان في فترة تاريخية (على سبيل المثال، 2-3 كتل في الماضي) بدلاً من الكتلة الحالية. تعمل كلتا الطريقتين على تقليل إمكانية تجميع القوة التصويتية بسرعة للتأثير على الأصوات على السلسلة.
المزيد عن تصميم أنظمة حوكمة آمنة (opens in a new tab)، آليات التصويت المختلفة في المنظمات المستقلة اللامركزية (دي إيه أوز) (opens in a new tab)، ومتجهات الهجوم الشائعة على المنظمات المستقلة اللامركزية (دي إيه أوز) التي تستفيد من دي فاي (opens in a new tab) في الروابط المشتركة.
8. تقليل التعقيد في الكود إلى الحد الأدنى
مطورو البرامج التقليديون على دراية بمبدأ KISS ("ابق الأمر بسيطًا، يا غبي")، الذي ينصح بعدم إدخال تعقيد غير ضروري في تصميم البرامج. ويأتي هذا في أعقاب التفكير السائد منذ فترة طويلة والذي مفاده أن "الأنظمة المعقدة تفشل بطرق معقدة" وتكون أكثر عرضة للأخطاء المكلفة.
إن إبقاء الأمور بسيطة له أهمية خاصة عند كتابة العقود الذكية، نظرًا لأن العقود الذكية من المحتمل أن تتحكم في كميات كبيرة من القيمة. نصيحة لتحقيق البساطة عند كتابة العقود الذكية هي إعادة استخدام المكتبات الموجودة، مثل عقود أوبن زبلين (opens in a new tab)، حيثما أمكن. نظرًا لأن هذه المكتبات قد تم تدقيقها واختبارها على نطاق واسع من قبل المطورين، فإن استخدامها يقلل من فرص إدخال الأخطاء عن طريق كتابة وظائف جديدة من البداية.
نصيحة شائعة أخرى هي كتابة وظائف صغيرة والاحتفاظ بالعقود المعيارية عن طريق تقسيم منطق الأعمال عبر عقود متعددة. لا تؤدي كتابة تعليمات برمجية بسيطة إلى تقليل مساحة الهجوم في العقد الذكي فحسب، بل تسهل أيضًا التفكير في صحة النظام العام واكتشاف أخطاء التصميم المحتملة مبكرًا.
9. الدفاع ضد ثغرات العقود الذكية الشائعة
إعادة الدخول (Reentrancy)
آلة إيثريوم الافتراضية (EVM) لا تسمح بالتنفيذ المتزامن، مما يعني أنه لا يمكن لعقدين مشاركين في استدعاء رسالة أن يعملان في الوقت نفسه. تؤدي المكالمة الخارجية إلى إيقاف تنفيذ العقد المستدعي والذاكرة مؤقتًا حتى عودة المكالمة، وفي هذه المرحلة يستمر التنفيذ بشكل طبيعي. يمكن وصف هذه العملية رسميًا بأنها نقل تدفق التحكم (opens in a new tab) إلى عقد آخر.
على الرغم من أن نقل تدفق التحكم إلى عقود غير موثوقة ليس ضارًا في الغالب، إلا أنه قد يسبب مشاكل، مثل إعادة الدخول. يحدث هجوم إعادة الدخول عندما يستدعي عقد ضار عقدًا ضعيفًا مرة أخرى قبل اكتمال استدعاء الوظيفة الأصلية. يتم شرح هذا النوع من الهجوم بشكل أفضل باستخدام مثال.
خذ بعين الاعتبار عقدًا ذكيًا بسيطًا ("الضحية") يسمح لأي شخص بإيداع وسحب الأثير:
1// هذا العقد ضعيف. لا تستخدمه في الإنتاج23contract Victim {4 mapping (address => uint256) public balances;56 function deposit() external payable {7 balances[msg.sender] += msg.value;8 }910 function withdraw() external {11 uint256 amount = balances[msg.sender];12 (bool success, ) = msg.sender.call.value(amount)("");13 require(success);14 balances[msg.sender] = 0;15 }16}إظهار الكليكشف هذا العقد عن وظيفة withdraw() للسماح للمستخدمين بسحب ETH المودعة مسبقًا في العقد. عند معالجة عملية السحب، يقوم العقد بالعمليات التالية:
- التحقق من رصيد ETH الخاص بالمستخدم
- يرسل الأموال إلى عنوان الاتصال
- يعيد رصيدهم إلى صفر، مما يمنع أي عمليات سحب إضافية من المستخدم.
تتبع وظيفة withdraw() في عقد Victim نمط "checks-interactions-effects" (فحص-تفاعلات-تأثيرات). إنه يفحص ما إذا كانت الشروط اللازمة للتنفيذ قد استوفيت (أي أن المستخدم لديه رصيد ETH إيجابي) وينفذ التفاعل عن طريق إرسال ETH إلى عنوان المتصل، قبل تطبيق تأثيرات المعاملة (أي تقليل رصيد المستخدم).
إذا تم استدعاء withdraw() من حساب مملوك خارجيًا (EOA)، فإن الوظيفة تنفذ كما هو متوقع: msg.sender.call.value() يرسل ETH إلى المتصل. ومع ذلك، إذا كان msg.sender هو حساب عقد ذكي يستدعي withdraw()، فإن إرسال الأموال باستخدام msg.sender.call.value() سيؤدي أيضًا إلى تشغيل الكود المخزن في ذلك العنوان.
تخيل أن هذا هو الكود المنشور في عنوان العقد:
1 contract Attacker {2 function beginAttack() external payable {3 Victim(victim_address).deposit.value(1 ether)();4 Victim(victim_address).withdraw();5 }67 function() external payable {8 if (gasleft() > 40000) {9 Victim(victim_address).withdraw();10 }11 }12}إظهار الكلتم تصميم هذا العقد للقيام بثلاثة أشياء:
- قبول إيداع من حساب آخر (من المحتمل أن يكون EOA الخاص بالمهاجم)
- إيداع 1 ETH في عقد الضحية
- سحب 1 ETH المخزنة في العقد الذكي
لا يوجد شيء خاطئ هنا، باستثناء أن Attacker لديه وظيفة أخرى تستدعي withdraw() في Victim مرة أخرى إذا كان الغاز المتبقي من msg.sender.call.value الوارد أكثر من 40,000. هذا يمنح Attacker القدرة على إعادة الدخول إلى Victim وسحب المزيد من الأموال قبل اكتمال الاستدعاء الأول لـ withdraw. تبدو الدورة على هذا النحو:
1- Attacker's EOA calls `Attacker.beginAttack()` with 1 ETH2- `Attacker.beginAttack()` deposits 1 ETH into `Victim`3- `Attacker` calls `withdraw() in `Victim`4- `Victim` checks `Attacker`’s balance (1 ETH)5- `Victim` sends 1 ETH to `Attacker` (which triggers the default function)6- `Attacker` calls `Victim.withdraw()` again (note that `Victim` hasn’t reduced `Attacker`’s balance from the first withdrawal)7- `Victim` checks `Attacker`’s balance (which is still 1 ETH because it hasn’t applied the effects of the first call)8- `Victim` sends 1 ETH to `Attacker` (which triggers the default function and allows `Attacker` to reenter the `withdraw` function)9- The process repeats until `Attacker` runs out of gas, at which point `msg.sender.call.value` returns without triggering additional withdrawals10- `Victim` finally applies the results of the first transaction (and subsequent ones) to its state, so `Attacker`’s balance is set to 0إظهار الكلالملخص هو أنه نظرًا لأن رصيد المتصل لم يتم تعيينه على 0 حتى اكتمال تنفيذ الوظيفة، فإن الاستدعاءات اللاحقة ستنجح وتسمح للمتصل بسحب رصيده عدة مرات. يمكن استخدام هذا النوع من الهجوم لاستنزاف أموال عقد ذكي، كما حدث في اختراق داو عام 2016 (opens in a new tab). لا تزال هجمات إعادة الدخول (reentrancy) مشكلة حرجة للعقود الذكية اليوم كما تظهر القوائم العامة لاستغلالات إعادة الدخول (opens in a new tab).
كيفية منع هجمات إعادة الدخول
أحد أساليب التعامل مع إعادة الدخول (reentrancy) هو اتباع نمط الفحص-التأثيرات-التفاعلات (checks-effects-interactions) (opens in a new tab). يقوم هذا النمط بتنظيم تنفيذ الوظائف بطريقة تجعل الكود الذي يقوم بإجراء الفحوصات الضرورية قبل التقدم في التنفيذ يأتي أولاً، ثم الكود الذي يتلاعب بحالة العقد، مع وصول الكود الذي يتفاعل مع العقود الأخرى أو نتائج التنفيذ أخيرًا.
يُستخدم نمط الفحص-التأثير-التفاعل في نسخة منقحة من عقد Victim الموضح أدناه:
1contract NoLongerAVictim {2 function withdraw() external {3 uint256 amount = balances[msg.sender];4 balances[msg.sender] = 0;5 (bool success, ) = msg.sender.call.value(amount)("");6 require(success);7 }8}يقوم هذا العقد بإجراء فحص على رصيد المستخدم، ويطبق تأثيرات وظيفة withdraw() (عن طريق إعادة تعيين رصيد المستخدم إلى 0)، ثم يشرع في تنفيذ التفاعل (إرسال ETH إلى عنوان المستخدم). يضمن هذا قيام العقد بتحديث تخزينه قبل المكالمة الخارجية، مما يلغي شرط إعادة الدخول الذي مكّن الهجوم الأول. لا يزال بإمكان عقد Attacker الاستدعاء مرة أخرى في NoLongerAVictim، ولكن نظرًا لأن balances[msg.sender] قد تم تعيينه على 0، فإن عمليات السحب الإضافية ستؤدي إلى حدوث خطأ.
خيار آخر هو استخدام قفل الاستبعاد المتبادل (يُطلق عليه عادةً "mutex") الذي يقفل جزءًا من حالة العقد حتى اكتمال استدعاء الوظيفة. يتم تنفيذ ذلك باستخدام متغير منطقي يتم تعيينه على true قبل تنفيذ الوظيفة ويعود إلى false بعد الانتهاء من الاستدعاء. كما هو موضح في المثال أدناه، فإن استخدام mutex يحمي الوظيفة ضد المكالمات المتكررة بينما لا تزال عملية الاستدعاء الأصلية قيد المعالجة، مما يوقف إعادة الدخول بشكل فعال.
1pragma solidity ^0.7.0;23contract MutexPattern {4 bool locked = false;5 mapping(address => uint256) public balances;67 modifier noReentrancy() {8 require(!locked, "Blocked from reentrancy.");9 locked = true;10 _;11 locked = false;12 }13 // هذه الوظيفة محمية بقفل تبادلي (mutex)، لذا لا يمكن لعمليات الاستدعاء المعاد دخولها من داخل `msg.sender.call` استدعاء `withdraw` مرة أخرى.14 // تقيّم جملة `return` إلى `true` لكنها لا تزال تقيّم جملة `locked = false` في المُعدِّل15 function withdraw(uint _amount) public payable noReentrancy returns(bool) {16 require(balances[msg.sender] >= _amount, "No balance to withdraw.");1718 balances[msg.sender] -= _amount;19 (bool success, ) = msg.sender.call{value: _amount}("");20 require(success);2122 return true;23 }24}إظهار الكليمكنك أيضًا استخدام نظام مدفوعات السحب (pull payments) (opens in a new tab) الذي يتطلب من المستخدمين سحب الأموال من العقود الذكية، بدلاً من نظام "مدفوعات الدفع (push payments)" الذي يرسل الأموال إلى الحسابات. يؤدي هذا إلى إزالة إمكانية تشغيل التعليمات البرمجية عن غير قصد في عناوين غير معروفة (ويمكن أيضًا منع بعض هجمات رفض الخدمة).
التدفق السفلي والعلوي للأعداد الصحيحة
يحدث تجاوز عدد صحيح عندما تقع نتائج عملية حسابية خارج النطاق المقبول للقيم، مما يؤدي إلى "تدحرجها" إلى أدنى قيمة قابلة للتمثيل. على سبيل المثال، يمكن لـ uint8 تخزين قيم تصل إلى 2^8-1=255 فقط. العمليات الحسابية التي تؤدي إلى قيم أعلى من 255 سوف تفيض (overflow) وتعيد تعيين uint إلى 0، على غرار كيفية إعادة تعيين عداد المسافات في السيارة إلى 0 بمجرد وصوله إلى الحد الأقصى لعدد الأميال (999999).
تحدث حالات نقص الأعداد الصحيحة لأسباب مماثلة: حيث تقع نتائج العملية الحسابية تحت النطاق المقبول. لنفترض أنك حاولت إنقاص 0 في uint8، فإن النتيجة ستلتف ببساطة إلى أقصى قيمة قابلة للتمثيل (255).
يمكن أن تؤدي كل من الفيضانات والنقصان في الأعداد الصحيحة إلى تغييرات غير متوقعة في متغيرات حالة العقد وتؤدي إلى تنفيذ غير مخطط له. فيما يلي مثال يوضح كيف يمكن للمهاجم استغلال الفائض الحسابي في عقد ذكي لإجراء عملية غير صالحة:
1pragma solidity ^0.7.6;23// هذا العقد مصمم ليعمل كخزنة زمنية.4// يمكن للمستخدم الإيداع في هذا العقد ولكن لا يمكنه السحب لمدة أسبوع على الأقل.5// يمكن للمستخدم أيضًا تمديد وقت الانتظار إلى ما بعد فترة الانتظار البالغة أسبوعًا واحدًا.67/*81. انشر TimeLock92. انشر Attack مع عنوان TimeLock103. استدعِ Attack.attack وأرسل 1 إيثر. ستتمكن فورًا من11 سحب الإيثر الخاص بك.1213ماذا حدث؟14تسبب الهجوم في فيضان (overflow) لـ TimeLock.lockTime وتمكن من السحب15قبل فترة الانتظار البالغة أسبوعًا واحدًا.16*/1718contract TimeLock {19 mapping(address => uint) public balances;20 mapping(address => uint) public lockTime;2122 function deposit() external payable {23 balances[msg.sender] += msg.value;24 lockTime[msg.sender] = block.timestamp + 1 weeks;25 }2627 function increaseLockTime(uint _secondsToIncrease) public {28 lockTime[msg.sender] += _secondsToIncrease;29 }3031 function withdraw() public {32 require(balances[msg.sender] > 0, "Insufficient funds");33 require(block.timestamp > lockTime[msg.sender], "Lock time not expired");3435 uint amount = balances[msg.sender];36 balances[msg.sender] = 0;3738 (bool sent, ) = msg.sender.call{value: amount}("");39 require(sent, "Failed to send Ether");40 }41}4243contract Attack {44 TimeLock timeLock;4546 constructor(TimeLock _timeLock) {47 timeLock = TimeLock(_timeLock);48 }4950 fallback() external payable {}5152 function attack() public payable {53 timeLock.deposit{value: msg.value}();54 /*55 إذا كان t = وقت القفل الحالي، فنحن بحاجة إلى إيجاد x بحيث يكون56 x + t = 2**256 = 057 لذا x = -t58 2**256 = type(uint).max + 159 لذا x = type(uint).max + 1 - t60 */61 timeLock.increaseLockTime(62 type(uint).max + 1 - timeLock.lockTime(address(this))63 );64 timeLock.withdraw();65 }66}إظهار الكلكيفية منع حدوث فيضان الأعداد الصحيحة وتدفقها الزائد
اعتبارًا من الإصدار 0.8.0، يرفض مُجمِّع سوليديتي الكود الذي يؤدي إلى حدوث تجاوزات وتدفقات صحيحة. ومع ذلك، يجب على العقود المترجمة بإصدار مترجم أقدم إما إجراء فحوصات على الوظائف التي تتضمن عمليات حسابية أو استخدام مكتبة (على سبيل المثال، SafeMath (opens in a new tab)) تتحقق من التدفق السفلي/العلوي.
التلاعب بالأوراكل
تقوم الأوراكل بجلب المعلومات من خارج السلسلة (offchain) وإرسالها إلى السلسلة (onchain) لتستخدمها العقود الذكية. باستخدام Oracles، يمكنك تصميم عقود ذكية تتفاعل مع أنظمة خارج السلسلة، مثل أسواق رأس المال، مما يؤدي إلى توسيع نطاق تطبيقاتها بشكل كبير.
ولكن إذا تم إتلاف أوراكل وإرسال معلومات غير صحيحة على السلسلة، فسيتم تنفيذ العقود الذكية بناءً على مدخلات خاطئة، مما قد يسبب مشاكل. هذا هو أساس "مشكلة أوراكل"، والتي تتعلق بمهمة التأكد من أن المعلومات من أوراكل البلوكشين دقيقة ومحدثة وفي الوقت المناسب.
وتتمثل إحدى المخاوف الأمنية ذات الصلة في استخدام أوراكل على السلسلة، مثل البورصة اللامركزية، للحصول على السعر الفوري للأصل. غالبًا ما تفعل منصات الإقراض في صناعة التمويل اللامركزي (دي فاي) ذلك لتحديد قيمة ضمانات المستخدم لتحديد المبلغ الذي يمكنه اقتراضه.
غالبًا ما تكون أسعار DEX دقيقة، ويرجع ذلك إلى حد كبير إلى قيام المحكمين باستعادة التكافؤ في الأسواق. ومع ذلك، فهي عرضة للتلاعب، وخاصة إذا كانت أوراكل السلسلة تحسب أسعار الأصول على أساس أنماط التداول التاريخية (كما هي الحال عادة).
على سبيل المثال، قد يقوم المهاجم برفع السعر الفوري للأصل بشكل مصطنع من خلال الحصول على قرض سريع قبل التفاعل مع عقد الإقراض الخاص بك. إن الاستعلام عن سعر الأصل في بورصة DEX من شأنه أن يعيد قيمة أعلى من المعتاد (بسبب "أمر الشراء" الكبير للمهاجم والذي يشوه الطلب على الأصل)، مما يسمح لهم بالاقتراض أكثر مما ينبغي. وقد تم استخدام مثل هذه "هجمات القروض السريعة" لاستغلال الاعتماد على أوراكل الأسعار بين تطبيقات دي فاي، مما كلف البروتوكولات ملايين الدولارات من الأموال المفقودة.
كيفية منع التلاعب بالأوراكل
الحد الأدنى لمتطلبات تجنب التلاعب بالأوراكل (opens in a new tab) هو استخدام شبكة أوراكل لامركزية تستعلم عن المعلومات من مصادر متعددة لتجنب نقاط الفشل الفردية. في معظم الحالات، تحتوي أوراكل اللامركزية على حوافز اقتصادية مشفرة مدمجة لتشجيع عقد أوراكل على الإبلاغ عن المعلومات الصحيحة، مما يجعلها أكثر أمانًا من أوراكل المركزية.
إذا كنت تخطط للاستعلام من أوراكل على السلسلة عن أسعار الأصول، ففكر في استخدام أوراكل يعتمد آلية السعر المتوسط المرجح بالزمن (TWAP). يقوم أوراكل TWAP (opens in a new tab) بالاستعلام عن سعر الأصل في نقطتين زمنيتين مختلفتين (والتي يمكنك تعديلها) ويحسب السعر الفوري بناءً على المتوسط الذي تم الحصول عليه. يؤدي اختيار فترات زمنية أطول إلى حماية بروتوكولك ضد التلاعب بالأسعار، حيث إن الطلبات الكبيرة التي يتم تنفيذها مؤخرًا لا يمكنها التأثير على أسعار الأصول.
موارد أمان العقود الذكية للمطورين
أدوات لتحليل العقود الذكية والتحقق من صحة الكود
-
أدوات ومكتبات الاختبار - مجموعة من الأدوات والمكتبات القياسية في الصناعة لإجراء اختبارات الوحدة والتحليل الثابت والتحليل الديناميكي على العقود الذكية.
-
أدوات التحقق الرسمي - أدوات للتحقق من الصحة الوظيفية في العقود الذكية وفحص الثوابت (invariants).
-
خدمات تدقيق العقود الذكية - قائمة بالمنظمات التي تقدم خدمات تدقيق العقود الذكية لمشاريع تطوير إيثريوم.
-
منصات مكافآت الأخطاء - منصات لتنسيق مكافآت الأخطاء ومكافأة الإفصاح المسؤول عن الثغرات الحرجة في العقود الذكية.
-
Fork Checker (opens in a new tab) - أداة مجانية عبر الإنترنت للتحقق من جميع المعلومات المتاحة بخصوص عقد منقسم (forked).
-
ABI Encoder (opens in a new tab) - خدمة مجانية عبر الإنترنت لتشفير وظائف عقد سوليديتي ووسيطات المنشئ.
-
Aderyn (opens in a new tab) - محلل سوليديتي ثابت، يتنقل عبر أشجار بناء الجملة المجردة (AST) لتحديد الثغرات المشتبه بها وطباعة المشكلات بتنسيق markdown سهل الاستخدام.
أدوات لمراقبة العقود الذكية
- تنبيهات تيندرلي في الوقت الفعلي (opens in a new tab) - أداة للحصول على إشعارات في الوقت الفعلي عند حدوث أحداث غير عادية أو غير متوقعة في عقودك الذكية أو محافظك.
أدوات للإدارة الآمنة للعقود الذكية
-
Safe (opens in a new tab) - محفظة عقود ذكية تعمل على إيثريوم وتتطلب عددًا أدنى من الأشخاص للموافقة على معاملة قبل أن تتم (M-of-N).
-
عقود أوبن زبلين (opens in a new tab) - مكتبات عقود لتنفيذ الميزات الإدارية، بما في ذلك ملكية العقد، والترقيات، وضوابط الوصول، والحوكمة، وإمكانية الإيقاف المؤقت، والمزيد.
خدمات تدقيق العقود الذكية
-
كونسنسيس Diligence (opens in a new tab) - خدمة تدقيق العقود الذكية التي تساعد المشاريع في نظام البلوك تشين البيئي على ضمان جاهزية بروتوكولاتها للإطلاق وبنائها لحماية المستخدمين.
-
CertiK (opens in a new tab) - شركة أمن بلوك تشين رائدة في استخدام تقنية التحقق الرسمي المتطورة على العقود الذكية وشبكات البلوك تشين.
-
تريل أوف بيتس (opens in a new tab) - شركة أمن سيبراني تجمع بين أبحاث الأمن وعقلية المهاجم لتقليل المخاطر وتحصين الكود.
-
PeckShield (opens in a new tab) - شركة أمن بلوك تشين تقدم منتجات وخدمات لأمن وخصوصية وسهولة استخدام نظام البلوك تشين البيئي بأكمله.
-
QuantStamp (opens in a new tab) - خدمة تدقيق تسهل التبني السائد لتقنية البلوك تشين من خلال خدمات تقييم الأمان والمخاطر.
-
أوبن زبلين (opens in a new tab) - شركة أمن عقود ذكية تقدم عمليات تدقيق أمنية للأنظمة الموزعة.
-
Runtime Verification (opens in a new tab) - شركة أمنية متخصصة في النمذجة الرسمية والتحقق من العقود الذكية.
-
Hacken (opens in a new tab) - مدقق أمن سيبراني ويب3 يطبق نهج 360 درجة على أمن البلوك تشين.
-
نيذرمايند (opens in a new tab) - خدمات تدقيق سوليديتي و Cairo، تضمن سلامة العقود الذكية وأمان المستخدمين عبر إيثريوم و ستارك نت.
-
HashEx (opens in a new tab) - تركز HashEx على تدقيق البلوك تشين والعقود الذكية لضمان أمان العملات الرقمية، وتقدم خدمات مثل تطوير العقود الذكية واختبار الاختراق واستشارات البلوك تشين.
-
Code4rena (opens in a new tab) - منصة تدقيق تنافسية تحفز خبراء أمن العقود الذكية على إيجاد الثغرات والمساعدة في جعل ويب3 أكثر أمانًا.
-
CodeHawks (opens in a new tab) - منصة تدقيق تنافسية تستضيف مسابقات تدقيق العقود الذكية للباحثين الأمنيين.
-
Cyfrin (opens in a new tab) - مركز قوي لأمن ويب3، يحتضن أمن العملات الرقمية من خلال المنتجات وخدمات تدقيق العقود الذكية.
-
ImmuneBytes (opens in a new tab) - شركة أمن ويب3 تقدم عمليات تدقيق أمنية لأنظمة البلوك تشين من خلال فريق من المدققين ذوي الخبرة وأفضل الأدوات في فئتها.
-
Oxorio (opens in a new tab) - خدمات تدقيق العقود الذكية وأمن البلوك تشين مع خبرة في EVM و سوليديتي و ZK وتقنية السلاسل المتقاطعة (Cross-chain) لشركات العملات الرقمية ومشاريع التمويل اللامركزي (دي فاي).
-
Inference (opens in a new tab) - شركة تدقيق أمني متخصصة في تدقيق العقود الذكية للبلوك تشين القائمة على EVM. بفضل مدققيها الخبراء، تحدد الشركة المشكلات المحتملة وتقترح حلولاً قابلة للتنفيذ لإصلاحها قبل النشر.
منصات مكافآت الأخطاء
-
Immunefi (opens in a new tab) - منصة مكافآت الأخطاء للعقود الذكية ومشاريع التمويل اللامركزي (دي فاي)، حيث يراجع الباحثون الأمنيون الكود، ويفصحون عن الثغرات، ويتقاضون أجرًا، ويجعلون العملات الرقمية أكثر أمانًا.
-
HackerOne (opens in a new tab) - منصة لتنسيق الثغرات ومكافآت الأخطاء تربط الشركات بمختبري الاختراق وباحثي الأمن السيبراني.
-
HackenProof (opens in a new tab) - منصة مكافآت أخطاء متخصصة لمشاريع العملات الرقمية (دي فاي، العقود الذكية، المحافظ، CEX والمزيد)، حيث يقدم متخصصو الأمن خدمات الفرز ويتقاضى الباحثون أجرًا مقابل تقارير الأخطاء ذات الصلة والمتحقق منها.
-
Sherlock (opens in a new tab) - ضامن في ويب3 لأمن العقود الذكية، مع مدفوعات للمدققين تدار عبر العقود الذكية لضمان دفع أجور عادلة للأخطاء ذات الصلة.
-
CodeHawks (opens in a new tab) - منصة تنافسية لمكافآت الأخطاء حيث يشارك المدققون في مسابقات وتحديات أمنية، و(قريبًا) في عمليات تدقيق خاصة بهم.
منشورات حول ثغرات واستغلالات العقود الذكية المعروفة
-
كونسنسيس: هجمات العقود الذكية المعروفة (opens in a new tab) - شرح سهل للمبتدئين لأهم ثغرات العقود، مع كود نموذجي لمعظم الحالات.
-
SWC Registry (opens in a new tab) - قائمة منسقة من عناصر تعداد نقاط الضعف الشائعة (CWE) التي تنطبق على عقود إيثريوم الذكية.
-
Rekt (opens in a new tab) - منشور يتم تحديثه بانتظام حول عمليات اختراق واستغلال العملات الرقمية البارزة، إلى جانب تقارير مفصلة بعد الحادثة.
تحديات لتعلم أمان العقود الذكية
-
Awesome BlockSec CTF (opens in a new tab) - قائمة منسقة من ألعاب الحرب (wargames) في أمن البلوك تشين، والتحديات، ومسابقات التقاط العلم (Capture The Flag) (opens in a new tab) وشروحات الحلول.
-
Damn Vulnerable دي فاي (opens in a new tab) - لعبة حرب (Wargame) لتعلم الأمن الهجومي لعقود التمويل اللامركزي (دي فاي) الذكية وبناء المهارات في صيد الأخطاء والتدقيق الأمني.
-
Ethernaut (opens in a new tab) - لعبة حرب (wargame) قائمة على ويب3/سوليديتي حيث يكون كل مستوى عبارة عن عقد ذكي يحتاج إلى "اختراقه".
-
HackenProof x HackTheBox (opens in a new tab) - تحدي اختراق العقود الذكية، تدور أحداثه في مغامرة خيالية. يمنح إكمال التحدي بنجاح أيضًا إمكانية الوصول إلى برنامج مكافآت أخطاء خاص.
أفضل الممارسات لتأمين العقود الذكية
-
كونسنسيس: أفضل ممارسات أمان عقود إيثريوم الذكية (opens in a new tab) - قائمة شاملة من الإرشادات لتأمين عقود إيثريوم الذكية.
-
Nascent: مجموعة أدوات الأمان البسيطة (opens in a new tab) - مجموعة من الأدلة وقوائم المراجعة العملية التي تركز على الأمان لتطوير العقود الذكية.
-
سوليديتي Patterns (opens in a new tab) - تجميع مفيد للأنماط الآمنة وأفضل الممارسات للغة برمجة العقود الذكية سوليديتي.
-
مستندات سوليديتي: اعتبارات أمنية (opens in a new tab) - إرشادات لكتابة عقود ذكية آمنة باستخدام سوليديتي.
-
معيار التحقق من أمان العقود الذكية (opens in a new tab) - قائمة تحقق من أربعة عشر جزءًا تم إنشاؤها لتوحيد أمان العقود الذكية للمطورين والمهندسين المعماريين ومراجعي الأمن والبائعين.
-
تعلم أمان وتدقيق العقود الذكية (opens in a new tab) - الدورة التدريبية النهائية لأمان وتدقيق العقود الذكية، مصممة لمطوري العقود الذكية الذين يتطلعون إلى رفع مستوى أفضل ممارساتهم الأمنية ليصبحوا باحثين في مجال الأمن.