Комментарии 15
А если первый найденный блок уже является нужным?
Я бы считал примерно так: фиксация числа от 0 до 9 в 10 раз уменьшает вычислительную мощность (9/10 хэшей отвергаются), осталось лишь посчитать новую долю вычислительной мощности. До снижения в 10 раз она составляла 20%, после — 2% от 82% (мощность всей сети тоже снизилась), итого примерно 2,44%. Тогда с вероятностью 2,44% выпадет нужное число, а с оставшейся — случайное, итого этот пул поднял вероятность с 10% до 2,44% + (100% — 2,44%) * 0,1 = 12,196%. Получается побольше.
Я бы считал примерно так: фиксация числа от 0 до 9 в 10 раз уменьшает вычислительную мощность (9/10 хэшей отвергаются), осталось лишь посчитать новую долю вычислительной мощности. До снижения в 10 раз она составляла 20%, после — 2% от 82% (мощность всей сети тоже снизилась), итого примерно 2,44%. Тогда с вероятностью 2,44% выпадет нужное число, а с оставшейся — случайное, итого этот пул поднял вероятность с 10% до 2,44% + (100% — 2,44%) * 0,1 = 12,196%. Получается побольше.
мощность всей сети тоже снизилась
Почему?
Я бы считал примерно так: фиксация числа от 0 до 9 в 10 раз уменьшает вычислительную мощность (9/10 хэшей отвергаются),
Имхо, хороший подход. Наглядно.
Таким образом если у нас хеш будет приводится к двузначному числу
uint random_number = uint(block.blockhash(blockNumber))%99;
то фиксация числа для майнера снижает вычислительную мощность в 100 раз.
А если первый найденный блок уже является нужным?
Тогда мы не можем говорить, о том что майнер манипулировал результатом.
Почему выборочное поведение для первого блока (нужный блок распространить, ненужный — выкинуть) не считается манипулированием, а такое же поведение для второго считается?
ну если присутствует
ненужный — выкинутьто считается
скажем мы реализуем лото "5 из 36"
(5!x31!)/36! => 120/45239040 = 0.000002653 => 0.0002653% найти 5 из 36.
Таким образом если мы в качестве источника рандомности берем хеши нескольких последовательных блоков, шансы отдельно взятого майнера повлиять на результат, настолько малы, что в большинстве случаев ними можно пренебречь, даже есть речь идет о розыгрыше денежных (ETH) призов.
Верно, но у этого подхода есть минусы. Пусть у вас есть метод calculateLotteryWinners, который смотрит на хэши последних 72 блоков. Для секьюрности вы должны заранее наложить несколько ограничений:
Первое, все голоса пользователей должна быть сделаны как минимум 72 блока назад(иначе злоумышленнику нужно было угадать меньше 72 хэшей, тяряем секьюрность).
Второе, метод должен быть вызван обязательно вами, и в определенный, заранее оговоренный номер блока. Иначе у вызывающего есть возможность выбрать удобную
последовательность хэшей. Если это делаете вы, то вас будут обвинять в возможности влиять на результаты. Если не вы, то отдаете такой инструмент в руки злоумышленнику.
Теперь вы обязаны иметь offchain-бота, который будет следить за блокчейном и дергать метод в нужным момент — это сложно и децентрализованно.
Ребята уже всё придумали. Возьмите хороший генератор случайных чисел, а seed позвольте загенерить пользователям вместе. Тогда атака возможна только при договоренности абсолютно всех участников, что бессмысленно.
Ознакомиться с подробным рассказом можно здесь
все голоса пользователей должна быть сделаны как минимум 72 блока назад
Естественно. Но на Этериум это не так много времени занимает.
Да и на практике в этом случае лучше реализовать приведение хешей 36 блоков к двузначным числам.
метод должен быть вызван обязательно вами
Как раз нет. Наоборот надо чтобы подсчет мог быть запущен трансакцией с абсолютно любого адреса.
и в определенный, заранее оговоренный номер блока
Не обязательно точно в этот блок. В любом блоке номер которого больше оределенного номера.
Я по такому принципу делал голосование акционеров в смарт-контракте с акциями coinoffering.github.io/dapp/#/smart-contract: голосовать могут только адреса у которых есть токены (акции), а трансакцию инициирующую подсчет голосов можно запустить с любого адреса, но сработает только если время блока больше времени окончания голосования.
Теперь вы обязаны иметь offchain-бота, который будет следить за блокчейном и дергать метод в нужным момент — это сложно и децентрализованно.
Это не будет приводить к централизации — может же каждый запустить, а бот может работать для подстраховки: проверять состояние смарт-контракта периодически, если надо, инициировать трансакцию запускающую подсчет хешей в «генераторе случайных чисел». Пример такого бота: github.com/thedeex/deex.price.setter — он у меня цены выставлял в смар-контакте в зависимости от текущего курса USD/ETH, принцип работы аналогичен.
у вызывающего есть возможность выбрать удобную
последовательность хэшей
Номер блока от которого надо считать назад должен заранее задаваться.
Возьмите хороший генератор случайных чисел, а seed позвольте загенерить пользователям вместе. Тогда атака возможна только при договоренности абсолютно всех участников, что бессмысленно.
Мне кажется описанный здесь подход проще.
Ну и вообще тут речь не только о лото и лотерях, просто это наиболее простой и наглядный пример. Речь вообще о надежном методе получения рандомных чисел на блокчейне.
Сеть даёт доступ только к последним 256 блокам. Cryptokitties тоже полагаются на хэши и, к примеру, когда выходят за границу, то берут хэш одного из последних. В этот момент появляется возможность атаки — дёргать метод, когда хэши нравятся. А 256 в масштабах сети настолько же немного, насколько и 72. Как вы предлагаете с этим бороться?
Хорошая статья по теме:
Арсений Реутов. Как обмануть криптоказино. Предсказываем случайные числа в умных контрактах Ethereum // «Хакер», 12.04.2018 // xakep.ru/2018/04/12/ethereum-cheating
Арсений Реутов. Как обмануть криптоказино. Предсказываем случайные числа в умных контрактах Ethereum // «Хакер», 12.04.2018 // xakep.ru/2018/04/12/ethereum-cheating
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Программирование генератора случайных чисел на Ethereum