Лора Шин – На шифре. Инсайдерская история криптовалютного бума (страница 31)
Кое-кто предостерегал остальных:
Смотрите шире: мы видим хреновый смарт-контракт и беспечных инвесторов. Они сами рисковали, инвестируя в него без юридической экспертизы. Не рискуйте из-за них репутацией Ethereum как независимой децентрализованной платформы, принимая такие поспешные решения, как хардфорки или откаты. Этим вы создадите очень опасный прецедент и дадите политическим органам повод вмешиваться в будущем, когда им захочется!
Один из руководителей биржи Bitfinex, Филип Поттер, выразился так:
это проблема DAO, а не ETH
Дино настаивал, что откат Биткойна в 2013 году и так создал прецедент. Фил спросил: «Если вы кинете биржи, выживет ли ETH?» Дино ответил «да» и снова попросил биржи остановить торговлю.
«В жопу этот койн», – написал Фил.
Дино настаивал, что Ethereum не оправится, если допустить атаку на The DAO и хакер продаст на биржах миллионы ETH. «Стоимость упадет до 0,50 доллара, – написал он. – Рассуждайте здраво. Непоправимая пиар-катастрофа».
Но, как заявил Тристан Д’Агоста из Poloniex: «Скорее, паника на рынке начнется, если блокчейн сочтут ненадежным».
К тому же, как писал Фил, «если какое-нибудь правительство поймет, что в потенциале может принудить DAO „без лидеров“ (или ETH, если на то пошло) к откату, это чревато последствиями, я тебе гарантирую».
Между тем команда Slock.it и другие разработчики, сидя в чатах, быстро поняли суть атаки. Еще 5 июня Кристиан Райтвисснер – разработчик, которого Гэвин отказывался признавать создателем Solidity, – послал электронные письма ключевым девелоперам с предупреждением о баге, использующем разницу смарт-контрактов с обычными финансовыми транзакциями. Если получить деньги у кассира или в банкомате в реальности, ваш баланс обновится после того, как вы их получите на руки. Но смарт-контракт меняет баланс в первую очередь. Иначе вредоносный смарт-контракт может заставить его начать процесс снова – на стадии снятия денег, до обновления баланса. Именно так и поступил напавший на The DAO. Это как подойти в банке к кассиру с амнезией, где у вас открыт счет на 259 долларов, снять 258 долларов, отвлечь его раньше, чем он обновит баланс на счете до 1 доллара, и попросить снять 258 снова, и снова, и снова, и снова (только в этом случае нападавший получал по 258 ETH).
9 июня Питер Вессенс, соучредитель Bitcoin Foundation, написал пост в блоге, назвав это «ужасной, ужасной атакой», а на следующий день сам Кристиан написал о принципе атаки.
Slock.it обнаружили уязвимость The DAO в функции, позволяющей людям выполнять предложения. Они нашли решение проблемы – теперь только оставалось, чтобы за него проголосовало большинство держателей. Еще член форума на DAOhub нашел в структуре The DAO баг под названием «контракт вознаграждения». Но на этом контракте деньги не хранятся, и 12 июня Стефан написал в блоге: «Фондам DAO ничего не грозит после обнаружения бага с „рекурсивным вызовом“ в смарт-контрактах Ethereum». Он уточнял: «Важный вывод: поскольку в аккаунте вознаграждений The DAO эфира нет, это НЕ является проблемой, ставящей фонды DAO под удар». Не встревожился даже Виталик. За день до этого он твитнул: «Я покупаю токены DAO с тех пор, как вышли новости об их безопасности».
Контракт вознаграждения был в The DAO потенциальной брешью, поскольку с ним мог взаимодействовать смарт-контракт, написанный неизвестными лицами. Проще говоря, если The DAO вкладывается во что-то прибыльное, прибыль от вклада поступает в контракт вознаграждения, чтобы она могла пропорционально выплачиваться всем вкладчикам по принципу дивидендов. Кристоф решил, что если кто-то уходит из The DAO, создавая дочернюю DAO, то у него должно остаться право на будущие вознаграждения от своих вкладов. Чтобы выполнить это обещание, The DAO просит человека назвать внешний адрес или контракт, куда переводить вознаграждения. (В Ethereum аккаунты могут принадлежать как людям, так и контрактам, и если послать транзакцию на аккаунт контракта, подключается его код – это как делать выбор в торговом автомате, выдающем в ответ товар.) Кристоф не был обязан предоставлять будущие вознаграждения тем, кто уходит из The DAO, но великодушно принял это решение и при этом оставил в коде коммент: «Будем хорошими, пусть получают вознаграждения». (В зависимости от того, как считать строчки кода, комментарий находился на 667 строке – или же на 666-й.)
Но, может, Кристоф и был хорошим, зато хакер – нет. Хакер знал, что функция splitDAO состоит из четырех шагов (происходящих за один сеанс): 1) уходящий из The DAO создает дочернюю DAO и направляет туда токены, которые сгорают; 2) главная DAO высылает в новую DAO эфир; 3) главная DAO шлет вознаграждение (на аккаунт, указанный держателем токенов); и 4) контракт обновляет баланс уходящего. У хакера был обычный адрес, но вредоносный контракт. Он сигнализировал: «Эй, я хочу вывести свои токены из The DAO», – а потом выслал туда свои 25 805 токенов DAO, чтобы начать вывод 258 ETH.
На втором шаге – на вопрос, куда слать деньги, – нападавший дал ответ. Еще 8 июня в 7:38 по берлинскому времени кто-то (позже определили, что это был держатель токенов DAO из Китая) создал дочернюю DAO (№ 59) под названием
lonely[15]
so lonely
14 июня китайский держатель токенов вложил 305 тысяч токенов через Kraken, а все оставшиеся токены – 306 914 – через Poloniex. Теперь дочерняя DAO 59 опустела.
В пятницу 17 июня 2016 года, в 5:34 по берлинскому времени, нападавший приступил к рекурсивному вызову, запрашивая вывод в свою дочернюю DAO 59. На третьем шаге, когда The DAO спросила, куда переводить вознаграждение, хакер предоставил аккаунт Ethereum своего вредоносного контракта. Контракт вознаграждения запинговал этот контракт, запрограммированный так, чтобы, получая пинг, каждый раз начинать процесс заново со второго шага – когда The DAO отправляет деньги в дочернюю DAO. И он повторял так раз за разом, переводя эфиры и не позволяя The DAO дойти до четвертого шага, когда баланс обновляется и больше средства не выводятся. В данном случае хакер занимался этим уже несколько часов, получая по 258,056565 ETH за раз. (Курс в тот день менялся, поэтому сумма варьировалась в пределах от 3 500 до 5 550 долларов). Рекурсивный вызов (он же атака повторного входа) происходил так быстро, что нападавший получал эту сумму почти каждую секунду – то есть, в зависимости от курса, от 210 тысяч до 330 тысяч долларов в минуту, или от 12,6 миллиона до 19,8 миллиона в час.
Но грабитель не мог просто забрать деньги и сбежать. Правила The DAO ограничивали и его. Через функцию вывода эфира из The DAO он мог отправлять деньги только в дочернюю DAO (шлюпку). (У контракта вознаграждения нет своих средств, поэтому, когда нападавший запрашивал сумму, на самом деле ему ничего не отправлялось.) И эти токены запирались в дочерней DAO 59 на двадцать восемь дней – или двадцать семь с чем-то, учитывая, что часики уже тикали. (Сплиты создаются как для вывода денег из системы, так и для создания новых DAO, и, если бы целью этого сплита было создать новую DAO с новыми задачами, тогда эти двадцать восемь дней были бы периодом создания, в течение которого в дочерний проект могут вступить и вложить свои средства другие люди.) Через двадцать восемь дней нападавший мог бы сделать другое предложение с семидневным периодом голосования, чтобы сплитнуться во
Поскольку пока было неизвестно, получится ли у Slock.it и других программистов остановить атаку, они решили заспамить сеть Ethereum, чтобы замедлить вывод средств. Это как искусственно создать на шоссе пробку, чтобы остановить машину грабителей.
Но это только временная заплатка – по двум причинам. Во-первых, тогда бы
Атака готовилась не один день. Во вторник 14 июня, через два дня после поста Стефана об уязвимости контракта вознаграждения и заявления, что все средства защищены, в 13:42 и затем в 23:05 по берлинскому времени хакер обменял биткойны на токены DAO с помощью ShapeShift – сначала 2 BTC за 7 910 токенов (1 321 доллар), далее тем же вечером – другие 2 BTC за 8 307 токенов (1 387 долларов), еще 2 BTC за 8 306 токенов и еще 1,4 BTC за 52,02 ETH (950 долларов). Он перевел все токены и эфиры на адрес, начинавшийся с 0x969.
В среду 15 июня, в 6:26 по берлинскому времени, хакер с двух разных контрактов проголосовал за создание дочерней DAO 59 (принадлежащей китайскому держателю, но пока пустой). Чуть больше часа спустя закончился семидневный период голосования, после чего к ней уже нельзя было присоединиться. Поскольку китайский держатель так и не проголосовал за собственное предложение, хакер остался единственным, кто имел право сплитнуться от DAO 59.