Эфириум обещает, что контракты будут «жить вечно» при настройках по умолчанию. Но фактически, кроме тех случаев, когда контракт относится к классу суицидников, они являются не разрушимыми. Это обоюдоострый меч. С одной стороны, режим самоубийства по умолчанию для контракта должен возвратить владельцу все средства, вложенные в контракт; это явно не осуществимо в системе с «нулевым доверием», в которой владелец контракта может присвоить все деньги.
Да, это хорошо позволить людям рассуждать о долговечности контракта. С другой стороны, недавно рассмотренные некоторые контракты на Эфириуме, и качество кода колебалось от «отвечает минимально необходимому качеству» до «ужасно» для кода, который разработан для того, чтобы выполняться вечно.
Дэн Майер цитирует исследования индустрии, согласно которым в среднем по индустрии на 1000 строк кода приходится 15-50 багов, а в коде релизов Microsoft то и 0.5 на 1000, и 0(!) дефектов в 500 000 линий кода для NASA, что потребовало очень дорогого и трудоемкого процесса.
В это же время количество багов в умных контрактах на Эфириуме превышает 100 на 1000 строк кода
Обзор умных контрактов на Эфириуме, доступный для проверки на dapps.ethercasts.com показал количество ошибок в 100 на 1000, может быть и больше.
Определение багов
3 категории багов (условное распределение):
1. Недостатки безопасности: возможности потери денег или контроля над средствами.
2. Не делает того, что указано в описаниях или комментариях кода.
3. Пропадает впустую или не эффективно расходуется газ.
Раньше была уверенность в большом количестве ошибок типа 3, и небольшом количестве ошибок типа 2. Озадачило, что на самом деле большинство ошибок были типа 1, часто сочетаясь с 2. Это вызвало своеобразный риторический вопрос; если контракты являются постоянными и не изменяемыми, а количество ошибок не приближается к нулю, что же люди подписывают?
Типичный контракт с несколькими недостатками
Ethstick представляет собой пирамидальную схему, которая стимулирует участников (ослов) продолжать вносить деньги, чтобы получить выплату (морковку). С приходом нового платежа, «счастливый осёл» выбирается для получения выплаты; счастливчик выбирается из общего списка ослов.
Платежи варьируются, от 1.1x до 1.2x, что настраивает владелец контракта. (Характерно, что названный «свинья» в коде). Эта свинья, то есть владелец, может продать контракт и передать его новому владельцу, что предлагается как общая модель для микро бизнеса.
Вы можете просмотреть код контракта
0xbA6284cA128d72B25f1353FadD06Aa145D9095Af на etherscan.io.
Случайность
Десятиминутная проверка показала пару серьезных проблем. Во-первых, функция случайности полагается только на определённые числа:
1. Пользовательское целое число, используемое в качестве фактора случайности, жестко вписано в контракт.
2. Используется хэш предыдущего блока Эфириума.
3. А также используется переменная — общий список ослов.
Это случайное число используется для того, чтобы определить, на какого из ослов приходится выплата. Блоки Эфириума появляются раз в примерно 45 секунд; так что у атакующего достаточно времени для того, чтобы определить осла, которому досталась выплата.
По мнение автора это можно назвать серьезной ошибкой. И это не смягчается популярностью контракта. Чем больше людей играет, тем больше вероятность вашей удачи. Но если контракт не используется часто, его нужно подталкивать, чтобы выплваты были получены. Здесь даже не очень хорошо использовать хэш блока: атакующий майнер или пул может включать только те транзакции в блок, которые ему нужны, в противном случае не пропуская их в сеть. Также пользователи подвержены атаке со стороны владельца контракта.
Какой длины список?
Функция changeEligibleDonkeys позволяет владельцу контракта скоращать или удлинять список ослов. Простое воздействие владельца могло бы быть таким:
1. Добавить себя в список ослов, имеющих право на выплату, возможно, многократно.
2. Сократить список, если «киты» собрались возле его конца.
Пропустили многие ошибки, связанные с «эффективностью», и не будем утверждать, что проанализировали все ошибки в этом коде.
Убрав пробелы и объявления данных, получили 350 строк кода или около того. Здесь обнаружилось две больших ошибки и как минимум пять, связанных с грубым округлением или не эффективностью кода. Действующая логика в коде занимает меньше чем 100 строк.
Это внушающее опасение количество ошибок, и я не отбирал контракт специально. Фактически, он даже лучше многих других контрактов. В конечном счёте из Эфириума получится выгребная яма для соревнования атакующих алгоритмов, за чем будет забавно наблюдать, но я не думаю, что это та работа, которую умные контракты должны делать.
На фоне того, на что я насмотрелся за последние несколько дней, это код среднего качества. Некоторые популярные сервисы, в том числе те, через которые проходят сотни тысяч долларов, крайне плохи (настолько, что «все участники могут потерять деньги»), по своей жестко запрограммированной структуре.
Смягчение
Некоторые рекомендации — во-первых, для самых простых контрактов может существовать механизм замены. У меня есть несколько идей по поводу того, как это может работать, и я опишу их позже, но здесь смущает то, что механизму замены потребуется доверие со стороны участников контракта.
Во-вторых, похоже, что имеет смысл включить режим суицида для большинства контрактов, и подумать над тем, как сделать это самым честным образом. В нашем случае это было бы честное начисление на балансы «ослов» и простой способ предусмотреть и предотвратить закрытие контракта с перечислением всего баланса в пользу владельца. В-третьих, аудит и страхование умных контрактов становятся необходимостью.
Примечание: Автор контракта ответил и объяснил некоторые вещи на reddit. Hacker News также втянулись в эту интересную дискуссию.