Помилка була в реалізації правила перевірки, а не в криптографії чи графіку емісії. Кожен вихід був додатним, але їхня сума через переповнення ставала від’ємною. Різниця між входом і цим від’ємним результатом виглядала як комісія. Версія 0.3.10 додала верхні межі для окремих виходів і поточної суми; після реорганізації на виправлену гілку хибний блок зник з активної історії.
15 серпня 2010 року розробник Jeff Garzik звернув увагу на дивний блок 74 638. Транзакція 1d5e512a9723cbef373b970eb52f1e9598ad67e7408077a82fdac194b65333c9 витратила єдиний вхід у 0,50 BTC і створила два величезні виходи. Тогочасний вивід printblock показує для кожного з них 92 233 720 368,54275808 BTC. Автора транзакції, що використала вразливість, достовірно не встановлено: публічний запис підтверджує її дані, а не особу чи мотив творця. [1]
Bitcoin тоді подавав суми як 64-бітові цілі числа зі знаком у сатоші. Цілочисельне значення кожного виходу, також зафіксоване шістнадцятковим записом 0x7ffffffffff85ee0, було додатним і трохи меншим за максимум int64. Проте сума 18 446 744 073 708 551 616 сатоші перевищила допустимий діапазон і перетворилася на −1 000 000 сатоші. Стара перевірка приймала цей від’ємний результат, порівнюючи його з входом. Це була арифметична помилка, а не злам підписів. Перший JSON-вивід у дискусії має інші останні цифри після коми; для точного розрахунку тут використано ціле значення, підтверджене і printblock, і шістнадцятковим записом. [1]
Від’ємна сума виходів −0,01 BTC за входу 0,50 BTC створювала видимість комісії 0,51 BTC. Тому майнер отримав у coinbase 50,51 BTC замість базової винагороди 50 BTC. Якщо відняти витрачений вхід і врахувати надлишок у coinbase, два величезні виходи збільшили пропозицію в хибній гілці рівно на 18 446 744 073 709 551 616 сатоші: 2^64 сатоші, або 184 467 440 737,09551616 BTC. Отже, це число не є просто сумою двох виходів. [2]
Спільнота реагувала публічно й під тиском часу. Lfm назвав помилку серйозною, Gavin Andresen запропонував швидко звіряти кожен вихід із 21 мільйоном BTC, а Satoshi Nakamoto оприлюднив ширше рішення: відхиляти від’ємний або завеликий вихід і завелику поточну суму після кожного додавання. Satoshi також попросив майнерів тимчасово зупинитися, щоб нова дійсна гілка могла швидше наздогнати й замінити хибну. [2]
Satoshi оголосив версію 0.3.10 15 серпня 2010 року о 23:48 за часом форуму, приблизно через п’ять годин сорок хвилин після повідомлення Garzik. Оновлені вузли вважали транзакцію та блок 74 638 недійсними й будували над останнім спільним чинним блоком. Згодом тогочасне оголошення повідомило, що добра гілка випередила погану, тому оновлений клієнт міг автоматично реорганізуватися без ручного видалення файлів blockchain. [3]
Старий блок не редагували в центральній базі. Існували дві конкурентні історії: старі вузли приймали блок за первинними правилами, а виправлені відхиляли його й визнавали лише роботу над чинним предком. Коли виправлена гілка накопичила більше Proof of Work, мережа пішла за нею, а інфляційний блок зник з активної історії; вирішальними були встановлення правил користувачами й майнерами та подальша робота, а не наказ адміністратора. [3]
Запроваджений тоді захист досі видно в Bitcoin Core. CheckTransaction відхиляє від’ємний вихід, вихід понад MAX_MONEY і поточну суму поза MoneyRange; перевірка після кожного додавання не дає небезпечній сумі переповнитися до порівняння. Коментар коду прямо посилається на CVE-2010-5139, а окрема перевірка повторних входів нагадує про інший інцидент CVE-2018-17144. [4]
Інцидент показує, що межа 21 мільйон не є магічною сталою, захищеною самим хешуванням: її забезпечують точні правила перевірки та правильна реалізація. Аудит має охоплювати діапазони значень, безпечне додавання, coinbase й комісії, порядок перевірок, граничні тестові вектори та збіг незалежних реалізацій. Історія водночас показує здатність ранньої спільноти швидко усувати помилки та її тодішню залежність від небагатьох розробників, майнерів і ручної координації. [5]
Для повної картини прочитайте також Bitcoin Core, Правила консенсусу, Транзакція, UTXO, Reorg, Soft Fork.
01Чи існували колись 184 мільярди BTC у чинному Bitcoin?+
Вони коротко існували в тоді видобутій хибній гілці як наслідок експлуатаційного блоку. Виправлені вузли відхилили її, а чинна гілка реорганізувала, тож величезні виходи не входять до сучасного активного blockchain чи набору UTXO. Сам історичний інцидент підтверджений блоком і тогочасною реакцією.
02Чи назавжди інцидент порушив межу 21 мільйон?+
Ні в історії, яку приймають сьогодні: виправлені правила консенсусу відхилили хибний блок, а його виходи зникли під час реорганізації. Подія показала, що межа залежить від правильної перевірки й фактично запущеного ПЗ; твердження в документації саме по собі не забезпечує пропозицію.