реклама
Бургер менюБургер меню

Лора Шин – На шифре. Инсайдерская история криптовалютного бума (страница 67)

18

Может, ему и было плохо, но дальше было только хуже. В 16:54 по центральноевропейскому летнему времени (CEST) в понедельник 6 ноября, пока бóльшая часть команды Parity отсыпалась после вчерашней церемонии, разработчик под ником ghost создал на GitHub пост «Любой может убить ваш контракт № 6995». В самом тексте говорилось: «Я его случайно убил». Затем ghost выложил ссылку на адрес в Etherscan. В 17:33 CEST devops199 выложил в Gitter Parity ссылку на проблему 6995 с вопросом: «Это серьезная проблема?» Никто не отвечал до 7:27 CEST следующего утра, когда кто-то написал:

Эй, ребят

А вы знаете, что ваш мультисиг хакнули?

Почему никто не реагирует?

На кошельках с мультисигом, ссылающихся на убитые библиотеки, заморожены миллионы долларов

То есть контракты мультисига не работают и эфир нельзя снять

До людей не сразу дошло, что на 587 кошельках заперто – заблокировано навсегда – полмиллиона эфира (на тот момент 150 миллионов долларов), а виновник, ghost/devops199, говорит, что сделал это случайно. Проблема оказалась в том самом коде, который команда Parity наспех написала в последнюю ночь гулянок на Ибице, когда выкладывала патч после первого хака кошельков. И в этом коде нашлась даже не одна, а две смертельные уязвимости. Если вкратце, Parity создали банк и сказали, что в его хранилище можно спокойно сдавать деньги, и люди принесли туда эфир на сотни миллионов долларов. Но оказалось, что владельца у банка нет, и тогда devops199 назначил владельцем себя – а потом закрыл двери и уничтожил ключ, навсегда заперев деньги внутри. Кое-кто подозревал злой умысел, но другие видели в этом оплошность: «Тот, кто убил библиотеку, совершил понятную ошибку. Могу легко представить, что сам сделал бы так же. Мне бы и в голову не пришло, что можно убить контракт, который создал не я». Эти люди считали, что devops199 убил контракт, просто пытаясь отменить свой статус «владельца банка».

В 14:29 CEST devops199 вошел в чат и написал просто:

:(

Немного погодя он добавил: «Меня за это посадят?:(»

«Ты убил tx [транзакцию]?» – спросил Tienus.

Devops199 ответил:

да

я eth-новичок… просто учусь

«Теперь ты знаменитость хаха», – ответил qx133.

Сам Гэвин узнал об этом в Цюрихе, сходя по трапу самолета. В тот момент у него уже начался жар.

Две ошибки Parity состояли в следующем: во-первых, они разрешили назначать владельца для общественной инфраструктуры, а во-вторых, разрешили владельцу убивать контракт, что devops199 и сделал для целой кучи Parity-кошельков. Среди 587 пострадавших кошельков несколько принадлежали тем, кто провел ICO и набил кошельки эфиром с краудфандинга, в том числе Iconomi, потерявшей 34 миллиона долларов, а также Musiconomi с ICO поменьше, лишившейся 4,8 миллиона.

Но в основном замороженные средства принадлежали самой Parity. В ее кошельке лежали 306 276 ETH (95 миллионов долларов) – 60 % всего заблокированного эфира; 586 кошельков составляли остальные 40 %. Parity будто создали банк для собственных денег, но кто-то, проходя мимо, случайно запер дверь и выбросил ключ.

На Reddit не могли поверить, что Parity-мультисиг взломали – опять – и что баг находился в «исправленном» коде после прошлого взлома. Один пользователь сказал: «Как Parity могут так безалаберно относиться к мультисиг-кошелькам?.. В такой ситуации я не поддерживаю полный возврат средств для Parity».

Еще обиднее то, что команду Parity об этом уже предупреждали в августе, когда кто-то с GitHub посоветовал «инициализировать» кошелек (то есть, условно, назначить владельца банка). В последующем анализе Parity упоминали об этой рекомендации, но сказали: «На тот момент это считалось всего лишь способом повысить удобство использования… и откладывалось на будущее, до следующего штатного обновления». Хотя один из пользователей Reddit указал, что это бы решило только первую проблему, а не вторую: «Даже после инициализации у кого-нибудь осталась бы возможность убить библиотеку. Если бы какой-нибудь обиженный работник решил после увольнения все спалить, у нас был бы очень похожий сценарий». Программисты, просмотрев код, в шоке обнаружили, что функции по назначению себя владельцем и убийству контракта шли одна за другой.

Следом дискуссия тут же перешла к обсуждению того, как достать запертый эфир, – и, естественно, в списке появился хардфорк. В среду утром по берлинскому времени Виталик уклончиво твитнул: «Я намеренно воздерживаюсь от комментария касательно проблем с кошельками, разве что выражаю поддержку тем, кто старается писать простые и безопасные контракты кошельков либо проверяет и формально подтверждает безопасность существующих».

Однако год назад он сам писал Предложение по улучшению Ethereum (Ethereum Improvement Proposal, EIP) № 156 под названием «Возвращение эфира в обычных классах заблокированных аккаунтов». Это предложение «позволит пользователям с эфиром или другими активами в обычных классах заблокированных аккаунтов выводить свои активы», писал он. EIP касалось случаев, когда случайно создан контракт без кода, когда проводятся атаки с повтором на ETC или если потери вызваны ошибкой в библиотеке JavaScript. Виталик писал: «Примечание: во всех этих случаях законный владелец очевиден, его право можно математически доказать, и ни один пользователь не лишился активов». Он признавал, что предложение лучше считать «„операцией по спасению“, а не „техническим усовершенствованием“», и предлагал обсудить его, а не одобрять сходу. Хотя он выложил EIP 156 14 октября 2016 года, дискуссия продолжалась и 17 августа 2017 года.

Ветка с комментариями обрела вторую жизнь 7 ноября, когда разошлись новости о взломе Parity. Правда, один пользователь отметил, что в данном виде предложение не разблокирует замороженные кошельки, потому что в их адресах все-таки есть код.

Хотя Виталик и не высказывал своего мнения, Гэвин все равно давил на него, чтобы он сохранял нейтралитет и не мешал Parity вернуть свои средства. (Гэвин утверждает, что никогда ни на кого не давит.) Виталик не встал в позу, но все-таки был против хардфорка – он чувствовал, что сообществу нужен новый прецедент, чтобы показать: форк после The DAO не значит, будто теперь этого может потребовать любой. Когда он вносил EIP 156, ситуация была совсем иной: сумма заблокированных средств составляла куда меньше 150 миллионов, и они были утрачены намного раньше. К тому же он нисколько не сочувствовал Parity. Это уже второй взлом их кошелька. И из замороженных 150 миллионов бóльшая часть принадлежала Parity. Более того, и остальные деньги принадлежали лишь трем ICO: Parity, Iconomi и Musiconomi владели 85 % средств. Во многих мультисиг-кошельках хранились небольшие суммы эфира – от пары сотен до нескольких десятых эфира. К тому же Parity уже давно выставляли себя так, будто они намного профессиональнее команды Geth. Виталик не видел необходимости высказывать личное мнение; он полагал, что сообщество само выступит против возврата средств.

И оказался прав: сообщество к этому времени уже изменилось. Тогда казалось, что The DAO – это и есть Ethereum. Теперь же в ходе ICO-бума народились всякие Golem, BAT, Bancor и Status (а также более сомнительные проекты вроде Veritaseum и Dentacoin), а CoinMarketCap насчитывал 1 205 монет против 614 во время атаки The DAO; то есть деньги теряла всего пара компаний в целой экосистеме. Быть может, сумма в долларах и превышала сумму, утраченную во времена The DAO, но только из-за выросшей стоимости эфира; число замороженных токенов – 513 774 – это лишь полпроцента от приблизительного количества эфира в обороте, а вовсе не 4,5 %, и абсолютное количество тоже меньше, чем 3,64 миллиона ETH, которые забрал хакер у The DAO.

Но самое главное – с тех пор изменился мир. Раньше Ethereum делал так много форков, что сообщество решило, будто у форка нет никаких последствий. Тогда опаснее было не форкнуться. Но после The DAO люди узнали, что хардфорк может породить очередной Ethereum. А это уже было опасно. Другой фактор – в отличие от случая с The DAO, сроки теперь не поджимали. Средства заморожены – и, если не предпринять меры, так и будут лежать себе замороженными вечно. В случае с The DAO время на спасение было ограничено и вынуждало как-то действовать. К тому же в Ethereum наделали уже столько новых токенов, что спорный хардфорк грозил породить в другом блокчейне самые разные активы-дубликаты: Very Classic Gnosis, Very Classic BAT, Very Classic Status и так далее.

Вряд ли помогало и то, что Гэвин сжег за собой так много мостов в сообществе, хотя вслух об этом не говорили. После постов с подделанной метрикой, призванной выставить Geth в не лучшем виде, после благодарности Виталику в желтой книге за «зерно идеи», после саботажа многомесячных усилий по получению либеральной лицензии для кодовой базы С++, после изменений в Parity-клиенте, приносящих пользу только его пользователям, у него осталось маловато сторонников, если вообще кто-то остался, кроме его же работников в Parity. Еще в августе Виталик твитнул скриншот самого первого имейла от Гэвина и поблагодарил его за вклад в Ethereum. Гэвин ответил:

Спасибо и тебе, @VitalikButerin – я бы никогда не смог создать #Ethereum без тебя:-)