1315 أغسطس 2010
يوم ظهور 184 مليار بيتكوين
تجاوزت معاملة واحدة فحوصات المبالغ، فأنشأت كمية من البيتكوين تفوق المعروض المخطط له بأضعاف هائلة. جاء الإصلاح خلال ساعات، لكن الحادثة أظهرت أن متانة القواعد النقدية تعتمد على سلامة الكود الذي يفرضها.
يوم الأحد، 15 أغسطس 2010، لفت Jeff Garzik الانتباه إلى الكتلة 74 638 التي عُدّنت للتو، وإلى مبلغ لم يكن ينبغي أن يوجد. فقد أنشأت معاملة واحدة مخرجين، تجاوزت قيمة كل منهما 92 مليار BTC. وكان مجموعهما يعادل قرابة تسعة آلاف ضعف المعروض المخطط للبيتكوين. وفي الساعة 18:08:49 UTC، فتح Garzik موضوعًا على المنتدى بعنوان «Strange block 74638» ونشر بيانات الكتلة. خلال دقائق اتضح أن الأمر ليس خطأ في مستكشف الكتل ولا فاصلة عشرية وُضعت في غير مكانها. لقد قبلت الشبكة كتلة تخالف قاعدتها النقدية نفسها. ولكي يظل المستخدمون واثقين من أن العملات لا يمكن صنعها كيفما اتفق، كان عليهم العثور على الخلل، وإصلاح البرنامج، وإقناع عدد كافٍ من المشاركين بمتابعة فرع آخر من السجل.
الكتلة الغريبة 74 638
كان منشور Garzik قصيرًا ومباشرًا. عرض هاش المعاملة ومخرجين هائلين. ثم أظهر سجل printblock نُشر لاحقًا في النقاش نفسه قيمتهما الدقيقة: احتوى كل منهما على 92 233 720 368.54275808 BTC. وكانت الكتلة تضم أيضًا معاملة coinbase مستقلة تدفع للمعدّن 50.51 BTC. وبالمقارنة مع المكافأة الأساسية المعتادة، وهي خمسون بيتكوين، بدا المخرجان عبثيين: لقد أنشأ شخص للتو أكثر من 184 مليار وحدة.
لم يُعرف اسم صاحب المعاملة، ولم يصدر عنه تفسير علني. تكشف السلسلة المحفوظة ما حدث، لكنها لا تكشف من استغل الخطأ أو ما كان هدفه. نسبتها إلى مخترق بعينه سيضيف إلى القصة معلومة لا توفرها المصادر. ما نعرفه هو أن المعاملة صُممت لاستغلال نقطة ضعف في التحقق.
قبلتها الشبكة لأن الكود القديم كان يفحص كل مخرج على حدة ثم يفحص مجموع المخرجات. كان كل مبلغ ضخم ضمن النطاق الذي يستطيع النوع العددي المستخدم تمثيله، لكن جمع المبلغين تجاوز حدّه الأعلى. التفّت القيمة إلى المجال السالب، فاستنتج الفحص التالي خطأً أن المعاملة لا تنشئ مبلغًا موجبًا غير مسموح به.
لم يكن الهجوم تزويرًا لتوقيع، أو تغييرًا في معاملة قديمة، أو استحواذًا على أغلبية معدل الهاش. استغل المهاجم طريقة تعامل هذا التنفيذ مع الأعداد الصحيحة. كانت القاعدة الحسابية «لا تُخرج أكثر مما يدخل» صحيحة، لكن تجاوز النطاق العددي منع البرنامج من تطبيقها كما أراد الناس.
كانت الكتلة قد دخلت بالفعل في السلسلة التي تتبعها الشبكة. اعتبرتها كل عقدة تستخدم الإصدار المعيب صالحة، وكان بوسع معدّنين آخرين البناء فوقها. لذلك لم يكن إعلان المشكلة كافيًا. كان على المجتمع التحرك قبل أن ينتشر السجل الخاطئ أكثر، وتبدأ تلك المخرجات الهائلة بالانتقال إلى معاملات أخرى.
خطأ بين القاعدة والآلة
كثيرًا ما يوصف حدّ 21 مليون بيتكوين بأنه قانون ثابت لا يتغير. كشفت الحادثة صورة أدق: فهذا الحدّ جزء من Consensus Rules التي يجب أن تطبقها البرامج وكل Full Node دون خطأ. وإذا اشتركت جميع برامج العقد الشائعة في التنفيذ المعيب نفسه، فقد تقبل مؤقتًا حالة تخالف القاعدة المقصودة.
تجاوز نطاق العدد الصحيح مشكلة معروفة منذ زمن في البرمجة. سجل الحاسوب لا يتسع لأعداد بلا حدود؛ وعند تجاوز الحدّ قد تنتهي العملية الحسابية إلى الطرف الآخر من خط الأعداد. في نظام محاسبي، يصبح هذا التفصيل حاسمًا. يجب فحص المجموع أثناء الحساب، لا بعد انتهائه فقط، وإبقاء كل مبلغ ضمن النطاق المسموح به.
لذلك يُجري Bitcoin Core الحالي عدة فحوصات منفصلة. لا يجوز أن يكون المخرج سالباً، ولا أن يتجاوز المعروض النقدي الأقصى، ويُعاد التحقق من المجموع التراكمي بعد كل عملية جمع. لم تنشأ هذه الأسطر بوصفها حذراً مجرداً، بل تحمل ذاكرة حادثة سمح فيها غياب حماية واحدة بأن تسجّل الشبكة معاملة مستحيلة اقتصادياً.
يوضح الخطأ أيضًا الفرق بين المواصفات التقنية وما يتوقعه الناس من النظام. لم يجادل أحد في المنتدى بجدية بأن هذه المبالغ الهائلة مشروعة لمجرد أن البرنامج القديم قبلها. اتفق المشاركون على أنها تخالف القاعدة المقصودة. لكن الاتفاق احتاج إلى وسيلة تقنية تنفذه: إصدار جديد يرفض الكتلة المعيبة.
هنا تتكامل أدوار الكود والناس. يحدد الكود بصورة حتمية أي كتلة تقبلها العقدة. ويقرر الناس أي كود يثبتون عندما يكتشفون تعارضًا مع القواعد المقصودة. لم تكن الحادثة تصويتًا على إصدار مزيد من العملات، بل سباقًا لاستعادة قاعدة كان المجتمع يعدّها أساسًا للنظام.
تكمن خطورة تجاوز النطاق في أن الآلة لا تدرك عبثية النتيجة التي يلاحظها الإنسان فورًا. يتعامل المعالج مع عدد مخزّن في مساحة محدودة؛ وإذا تجاوز الحساب حدودها، فقد تلتف النتيجة إلى جزء آخر من النطاق. كان الكود القديم يفحص المخرجات منفردة، لكنه لم يحافظ على المجموع التراكمي ضمن حدود آمنة. وهكذا اجتازت المعاملة شروطًا تبدو معقولة كلٌّ على حدة، مع أنها خالفت الغرض المشترك منها. كان الإصلاح يحتاج إلى قاعدة فعلية في الكود: لا يكفي أن يكتب المطور في تعليق أن عدد البيتكوين لن يتجاوز 21 مليونًا. كانت كل عقدة بحاجة إلى ما يفرض هذا الحدّ في كل عملية حسابية.
الإصلاح تحت الضغط
بعد الإعلان ظهرت في المنتدى توصية بالتوقف عن قبول المعاملات وإيقاف التعدين مؤقتًا. فكل كتلة جديدة تُبنى فوق المعاملة المعيبة تزيد العمل الذي سيتعين التخلي عنه. لم يكن في الشبكة مفتاح إيقاف مركزي يستطيع Satoshi استخدامه لإيقاف التعدين. كان بوسعه نشر الإصلاح وإقناع المشغّلين بتشغيله.
أدخل الإصدار 0.3.10 فحوصات صحيحة للمبالغ ورفض الكتلة 74 638. عادت العقد المُصلَّحة إلى آخر نقطة مشتركة صالحة، وبدأ المُعدِّنون ببناء فرع بديل دون المعاملة التضخمية. تنافس تاريخان لفترة من الوقت بحسب العمل المُستثمَر.
أعلن Satoshi لاحقًا أن السلسلة الصحيحة تجاوزت السلسلة الخاطئة. نفذ البرنامج المحدّث إعادة تنظيم السلسلة، واختفت الكتلة المعيبة من السجل النشط. أما معاملات الفرع المتروك التي كانت صالحة في ذاتها، فكان يمكن أن تعود إلى قائمة الانتظار وتُدرج لاحقًا في كتل أخرى. لكن المخرجات الهائلة لم تكن قادرة على اجتياز الفحوصات الجديدة.
كان للإصلاح ثمن. خسر معدّنو الفرع المتروك مكافآتهم، واضطر المستخدمون إلى قبول أن عدة ساعات من السجل لن يستمر البناء عليها. في عام 2010 كانت الشبكة صغيرة وكان التنسيق سريعًا. أما الخطوة نفسها في منظومة أكبر بكثير فستشمل أطرافًا اقتصادية أكثر، ونسخًا برمجية متنوعة، وخلافات أوسع حول الحدود الدقيقة للإصلاح.
كثيرًا ما تُروى سرعة الاستجابة وكأنها تدخل خارق من Satoshi. لكنها تألفت في الواقع من خطوات يمكن تتبعها: نشر Garzik المشكلة، وحلل آخرون تجاوز النطاق العددي، وأعد المطورون التعديل، وثبّت المشغّلون نسخة جديدة من عميل Bitcoin، وقدم المعدّنون العمل للفرع الصحيح. كان بوسع المؤلف اقتراح الإصلاح، لكن الشبكة هي التي كان عليها تبنيه بالفعل.
أقسى قانون يحتاج إلى تطوير أكثر تواضعا
بعد الإصلاح عاد عدد البيتكوين الصالح إلى النطاق المقصود، ولم يعد ممكنًا إنفاق المليارات التي نشأت خطأً على السلسلة المستمرة. لذلك لم تؤد الحادثة إلى تضخم دائم. ومع ذلك، فهي ليست مجرد واقعة غريبة من نسخة تجريبية. إنها تذكير بأن الثقة في القواعد النقدية تأتي من برنامج يُختبر مرارًا، لا من شعار.
غالبًا ما تُقارن Bitcoin بأنظمة تستطيع فيها سلطة مركزية تغيير المعروض بقرار. لكن دور الناس لم يختفِ هنا أيضًا. يكتب المطورون البرامج، ويبحث المراجعون عن الأخطاء، ويختار المشغّلون الإصدارات، ويُنتج المعدّنون ترتيب الكتل. الفرق أن التدخل علني، وأن كل عقدة تستطيع بنفسها رفض القواعد التي لا توافق عليها.
تفسر الحادثة أيضًا الحذر الذي يرافق اليوم تعديل كود الإجماع. فقد يكون لتحسين حسابي صغير أثر نقدي. الاختبارات والفحوصات المتعددة للتنفيذ والمراجعة المتأنية ليست أعباء بيروقراطية زائدة؛ إنها دفاع ضد تكرار لحظة حوّلت فيها بضعة بتات مبلغًا بالمليارات من قيمة غير مقبولة إلى قيمة تبدو صالحة.
لم يجعل Jeff Garzik الشبكة آمنة بمنشور واحد، لكنه أظهر فائدة دفتر الحسابات العام. استطاع أي شخص رؤية الكتلة الغريبة، وإعادة جمع مخرجاتها، وفحص الإصلاح. لم يكن الخطأ مخفيًا في قاعدة بيانات داخلية لدى أحد المشغّلين، بل كان أمام المجتمع كله، ومعه الدليل على أن العقد القديمة قبلته.
نجا حدّ المعروض من الحادثة، لكن ليس بالطريقة التي قد توحي بها كلمة «ثابت». فالبرنامج كان قادرًا على الفشل وقد فشل بالفعل. ما أتاح التعافي هو أن الفشل كان ظاهرًا، وأن هناك قاعدة مشتركة يمكن الرجوع إليها، وأن عددًا كافيًا من المشاركين طبّق الإصلاح. قصة 184 مليار بيتكوين لا تنفي محدودية المعروض؛ إنها تروي ما يتطلبه الحفاظ عليها فعليًا.
تذكّرنا هذه الحادثة أيضًا بأنّ علنية الكود بحدّ ذاتها لا تُزيل الخطأ. أتاح المصدر المفتوح للناس أن يجدوا المشكلة ويقارنوها ويصلحوها دون انتظار مورد واحد، لكنّ الحاسم كان انتباه مشاركين محدّدين. كان لا بدّ أن ينتبه أحدهم إلى أرقام مستحيلة، وأن يجد آخر شرطًا معيبًا، وأن يتبنّى المشغّلون التحديث. أوجدت الشفافية إمكانية الرقابة؛ ولم يتحوّل ذلك إلى دفاع عن الشبكة إلّا بفعل الإجراء. لهذا تبقى القصة مهمّة حتى بعد سنوات: أمان البيتكوين لا يكمن في فكرة برنامج أصلي مثاليّ، بل في الجمع بين قواعد دقيقة، وتحقّق مستقلّ، وقدرة على الاستجابة للخطأ دون إخفائه.
الشخصيات والمفاهيم في الأطلس
المصادر وحدود القصة
- 01BitcoinTalk — Strange block 74638
تحذير Jeff Garzik الأصلي، والقيم الدقيقة للمخرجات، وتحليل تجاوز النطاق العددي، والتسلسل الزمني للاستجابة.
- 02BitcoinTalk — overflow bug SERIOUS
تنسيق التطوير في ذلك الوقت، وتصحيح خطأ التحقق، والانتقال إلى السلسلة المصلحة.
- 03Bitcoin Core — transaction consensus checks
التنفيذ الحالي لفحوصات نطاق قيم المخرجات منفردة ومجموعها.