Генераторы случайных чисел в смарт-контрактах

В этой статье рассматриваются алгоритмы генерации псевдослучайных чисел в смарт-контрактах на solidity. Предполагается, что читатель понимает работу Ethereum на логическом уровне.

Начнём

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

Полностью безопасного способа получить случайное число в solidity в сегодня не существует. Единственным источником энтропии в блокчейне являются хэши блоков, но они подвержены влиянию майнеров. Внешние источники энтропии также могут быть уязвимы, либо зависят от действий пользователей, что приводит к блокировке работы алгоритма при их бездействии. Поэтому при разработке и использовании ГПСЧ разработчику нужно понимать мотивацию каждой из сторон. В статье рассмотрены различные алгоритмы ГПСЧ на solidity, их уязвимости, области применения и условия, при которых использование ГПСЧ можно считать безопасным. Также приведены краткие выводы о том, в каких случаях предпочтительнее использовать тот или иной алгоритм.

Принципы разработки

Смарт-контракты выполняются в детерминированной среде, поэтому источником энтропии для ГСЧ могут быть только внешние данные. Основная задача разработки ГСЧ на ethereum заключается в реализации надежного источника энтропии.

Варианты получения энтропии:

  • Использование хэшей будущих блоков ethereum или bitcoin через BTCRelay.
  • Схема commit-reveal. Получение энтропии в несколько этапов, исключающих манипуляции с источником энтропии.
  • Схема, не исключающая возможность манипуляций с источником энтропии, но делающая такие манипуляции экономически невыгодными.
  • Централизованный доверенный источник энтропии. (oracle)

Рассмотрим алгоритмы работы каждого варианта и уязвимости, которым они могут быть подвержены.

Использовании хэша будущего блока

Схема работы алгоритма

В смарт-контракте вызывается функция, которая сохраняет номер текущего блока N и блокируется, пока не будет получено достаточно подтверждений, например, пока не будет смайнен блок N+20.

При повторном вызове функции на основе хэша блока N (опционально + хэши нескольких блоков после N) генерируется случайное число. Если блок N был больше 256 блоков назад, то его хэш будет равен 0, поэтому необходимо либо прерывать работу смарт-контракта, либо использовать более свежий блок, например, N + 256.

Уязвимости

В ethereum хранятся хэши только 256 последних блоков, поэтому если подтверждение не поступило вовремя, хэш блока всегда будет 0. Пример использования уязвимости: [SmartBillions lottery contract just got hacked! : ethereum]

Этот способ тем не менее возможно применять, если в случае устаревшего блока прибавлять 256 к номеру блока, пока его хэш не станет отличаться от 0. Такой подход используется в проекте crypto kitties [3].

Этот подход не исключает манипуляцию майнерами и безопасен только если потенциальное вознаграждение значительно меньше затрат на манипуляцию.

Также, способ не является детерминированным в случае устаревания блоков. Хэш будет меняться каждые 256 блоков, т.е. каждые 43 минуты, если новый блок создается раз в 10 секунд.

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

Путем симуляции атаки [GitHub - Bunjin/Rouleth: Roulette Smart Contract on Ethereum Blockchain] были получены данные о затратах на манипуляцию в зависимости от доли хэшрейта пула.

Анализ сималяции показал, что атакующий должен обладать по крайней мере 3% от мощности сети. В таком случае атакующий будет терять около 23 ETH за неопубликованный валидный блок. Эта сумма однако уменьшается с ростом вычислительной мощности атакующего. При обладании 10% от мощности сети потери будут составлять всего 2 ETH за блок. При 25% – 1.2 ETH. Если атакующему принадлежит 51% мощности сети, то потери снизятся до 0.5 ETH за блок, но в таком случае вся сеть будет находиться в опасности намного более серьезной, чем взлом одного смарт-контракта. [7]

Еще один пример расчета вероятности атаки – статья [Программирование генератора случайных чисел на Ethereum / Хабр], но в ней не учитывается возможность отправить блок как uncle.

Следует иметь в виду, что приведенные суммы потерь рассчитаны для сети ethereum и зависят от сложности сети и вознаграждения за блок. В сетях, использующих merged-mining или proof of stake, сложность сети значительно меньше, чем в сетях, использующих proof of work, поэтому использование хэшей блока в них менее безопасно, чем в ethereum.

Продолжение статьи читайте по ссылке: https://vc.ru/dev/62779-generatory-sluchaynyh-chisel-v-smart-kontraktah

 

15 мая 2019
Последние посты