В свете недавних событий с DAO проблемы безопасности "умных контрактов" на платформе Эфириума стали очевидны. Но еще за несколько недель до взлома бывший председатель совета Bitcoin Foundation Питер Вессенес описал и классифицировал, когда могут проявиться эти уязвимости. Ниже мы приводим перевод его статьи о возможных ошибках смарт-контрактов и чем это может угрожать.

Смарт-контракты и ошибки программирования

Создатели Эфириума обещают, что контракты будут "жить вечно", по умолчанию. И в самом деле, если в договоре не содержится положение о самоликвидации, они действительно могут существовать долго и без изменений.

Но это палка о двух концах. С одной стороны, режим ликвидации контракта по умолчанию может понадобиться, чтобы вернуть все денежные средства, вложенные в контракт владельца; но с другой сторонам договора явно нежелательно иметь систему «нулевого доверия», в которой владелец контракта может по своему желанию автоматически требовать возврата всех средств.

Таким образом, с одной стороны хорошо дать людям долговечные контракты. С другой стороны, я просмотрел некоторые контракты Эфириума и ощущения возникают достаточно неоднозначные, качество кода находится где-то между "оптимистично достаточным" и "ужасным", для кода, который должен работать вечно.

Дан Мейер демонстрирует исследования, показывающие, что в среднем по криптовалютной отрасли ошибок на 1000 строк кода где то в диапазоне от 15-50, Microsoft выпускает код с 0.5 ошибочных решений на 1000 строк, и лучший результат - 0 дефектов в 500 000 строках кода у НАСА, с очень дорогим и длительным процессом работы.

Мой обзор смарт-контрактов Эфириума, доступных для просмотра на dapps.ethercasts.com, показывает вероятный коэффициент ошибок, что-то вроде 100 на 1000, но может быть и выше.

Сообщения об ошибках и определения

Я классифицировал ошибки, разбив их на три категории:

  • Недостатки безопасности, которые могут быть связаны с потерей денег или контроля за контрактом для пользователей или владельцев.
  • Не выполняется то, что ожидается от контракта, этого нет в описании или в комментариях к коду.
  • Комиссии (газ) весьма неэффективны.

Перед началом этого краткого обзора я ожидал увидеть достаточное количество недостатков в пункте 3, и немного в п.2. Я был удивлен, увидев некоторые значительные ошибки, относящиеся к п.1, часто в сочетании с п. 2. В этой связи, возникает своего рода риторический вопрос. Если контракты статичны и постоянны, и частота ошибок не стремится к нулю, то на что клиенты подписываются?

Образец контракта с некоторыми недостатками

Ethstick является своего рода схемой пирамиды, которая состоит из участников (ослов), которые хотят сохранить свои вложения и получить выплату (морковку). Каждый платеж приходит, по принципу "повезло ослу", который был выбран для выплаты; счастливчик выбирается из списка приемлемых ослов. 

Выплаты варьируются между 1.1x и 1.2x и регулируются собственником контракта (так называемой "свиньей" в коде). Свинья-владелец может продать контракт или передать его новому владельцу, таков общий шаблон для подобных контрактов.

Вы можете просмотреть код контракта 0xbA6284cA128d72B25f1353FadD06Aa145D9095Af в etherscan.io.

Хаотичность

10-минутная проверка кода поднимает пару основных вопросов. Во-первых, случайная функция опирается только на произвольное целое число, используемое в качестве случайного фактора, жёстко прописанное в контракте. Это число может соответствовать:

  • Хэшу предшествующего уровня блока.
  • Номерам участников из списка (ослов)

Это случайное число используется для выбора того, какой из "ослов" получает выплату. Блоки Эфириума приходят примерно через каждые 45 секунд. Таким образом, у злоумышленников достаточно много времени, чтобы вычислить, какой из ослов получит выплату, и им остается только переадресовать контракт с оплатой и заменить собой получателя. Это квалифицируется как серьезное ошибка. 

Функция changeEligibleDonkeys позволяет владельцу контракта сократить или удлинить список участников-ослов. Самая простая атака на владельца контракта будет выглядеть как простое добавление в список приемлемых участников (ослов) несколько раз.

Я пропустил ряд "эффективных решений", связанных с ошибками, и не стал бы утверждать, что увидел все логические ошибки в этом коде. Для этого есть есть раздел с комментариями.

Количество ошибок настораживает, хотя этот контракт выглядит довольно функционально и работоспособно по сравнению с остальными. 

Некоторые популярные контракты, через которые проходит до 100 тысяч долларов платежей, выглядят также удручающе плохо, поскольку там любой может потерять все свои деньги без возможности компенсации.

Смягчение

Некоторые рекомендации:

  1. Для всех контрактов, кроме самых простых, должно быть обязательное требование к механизму замены условий. У меня есть несколько идей о том, как это могло бы работать, и я буду писать о них позже. Один очевидный момент состоит в том, что механизм замены должен быть у доверенного пользователя договора.
  2. Дтносительно механизма самоликвидации контракта: например, владелец контракта мог бы легко включить какую-то справедливую пропорциональную выплату остатков для участников-«ослов», не оставляя себе ничего, что позволило бы просто закрыть контракт, без лишних стимулов для владельца контракта попытаться украсть оставшиеся средства.
  3. Умный контракт или договор с проведением аудита и страхования будет хорошим решением и оградит нас от большинства проблем.