Ethereum приобрёл огромную популярность как платформа для первичного размещения монет (ICO). Однако она используется не только для токенов ERC20. Рулетки, лотереи и карточные игры — всё это можно реализовать на блокчейне Ethereum. Как любая реализация, блокчейн Ethereum не поддаётся подделке, он децентрализован и прозрачен. Ethereum допускает выполнение тьюринг-полных программ, которые обычно пишут на языке программирования Solidity. По словам основателей платформы, это превращает систему во «всемирный суперкомпьютер». Перечисленные характеристики полезны в приложениях для азартных игр, где особенно важно доверие пользователей.
Блокчейн Ethereum является детерминированным и поэтому представляет определённые сложности при написании генератора псевдослучайных чисел (ГПСЧ) — неотъемлемой части любого приложения для азартных игр. Мы решили исследовать смарт-контракты, чтобы оценить безопасность ГПСЧ на Solidity и подчеркнуть характерные ошибки проектирования, которые ведут к появлению уязвимостей и возможности предсказания будущего состояния ГПСЧ.
На etherscan.io и GitHub собрана информация о 3649 смарт-контрактах.
Контракты импортировались в свободную поисковую систему Elasticsearch.
С помощью веб-интерфейса Kibana для функционального поиска и фильтрации найдены 72 уникальные реализации ГПСЧ.
После ручной оценки 43 смарт-контракта признаны уязвимыми.
Уязвимые приложения
Анализ выявил четыре категории уязвимых ГПСЧ:
ГПСЧ с использованием переменных блока как источника энтропии.
ГПСЧ на основе хэша какого-то предыдущего блока.
ГПСЧ на основе хэша предыдущего блока в сочетании с якобы секретным начальным числом (seed).
ГПСЧ, подверженные уязвимости с опережением транзакции (front-running).
Посмотрим на примеры уязвимого кода в каждой категории.
ГПСЧ с использованием групп переменных
Вот некоторые переменные блока, которые ошибочно принимают за источник энтропии:
block.coinbase — адрес майнера, который нашёл текущий блок.
block.difficulty — относительный показатель сложности при майнинге текущего блока.
block.gaslimit — максимальное потребление газа для транзакций в блоке.
block.number — высота текущего блока.
block.timestamp — отметка времени, когда найден блок.
Прежде всего, майнеры могут манипулировать всеми переменными блока, так что по одной этой причине их нельзя использовать как источник энтропии. Что ещё более важно, переменные блока очевидно одинаковы в пределах блока. Так что если контракт злоумышленника обращается к контракту жертвы через внутреннее сообщение, то одинаковый ГПСЧ в обоих контрактах выдаст одинаковый результат.
ГПСЧ на хэша блока
У каждого блока в цепочке Ethereum есть проверочный хэш. Виртуальная машина Ethereum Virtual Machine (EVM) позволяет получать эти хэши с помощью функции block.blockhash(). Функция получает на вход числовой аргумент с указанием номера блока. В ходе этого исследования мы обнаружили, что результаты выполнения функции block.blockhash() зачастую некорректно используются в реализациях ГПСЧ.
Есть три основных разновидности таких уязвимых ГПСЧ:
block.blockhash(block.number), хэш текущего блока.
block.blockhash(block.number - 1), хэш последнего блока.
block.blockhash(), хэш блока, который отстоит как минимум на 256 блоков от текущего.
Посмотрим на каждый из этих случаев.
block.blockhash(block.number)
Переменная состояния block.number позволяет узнать высоту текущего блока. Когда майнер забирает транзакцию, которая выполняет код контракта, то известна переменная block.number будущего блока с этой транзакцией, так что контракт может надёжно получить её значение. Однако в момент выполнения транзакции в EVM хэш создаваемого блока по очевидным причинам ещё не известен, а EVM всегда будет выдавать нуль.
Привет! Я робот. Хозяин поручил мне проголосовать за Ваш пост! Я нашла похожий контент, который может быть интересен читателям ГОЛОСа:
https://habrahabr.ru/post/348838/
@fausethub, поздравляю! Вы добились некоторого прогресса на Голосе и были награждены следующими новыми бейджами:
Награда за количество полученных голосов
Вы можете нажать на любой бейдж, чтобы увидеть свою страницу на Доске Почета.
Чтобы увидеть больше информации о Доске Почета, нажмите здесь
Если вы больше не хотите получать уведомления, ответьте на этот комментарий словом
стоп
@fausethub, поздравляю! Вы добились некоторого прогресса на Голосе и были награждены следующими новыми бейджами:
Вы написали свой первый комментарий
Вы можете нажать на любой бейдж, чтобы увидеть свою страницу на Доске Почета.
Чтобы увидеть больше информации о Доске Почета, нажмите здесь
Если вы больше не хотите получать уведомления, ответьте на этот комментарий словом
стоп