Pull to refresh

Comments 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 хэшей отвергаются),

Имхо, хороший подход. Наглядно.

Таким образом если у нас хеш будет приводится к двузначному числу
uint random_number = uint(block.blockhash(blockNumber))%99;

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

Тогда мы не можем говорить, о том что майнер манипулировал результатом.
Почему выборочное поведение для первого блока (нужный блок распространить, ненужный — выкинуть) не считается манипулированием, а такое же поведение для второго считается?
ну если присутствует
ненужный — выкинуть
то считается
Так в статье рассматривается вариант, если первый блок выкидывается всегда. В 2% случаев мы выкинули блок, который дал бы нужное число, поэтому и итоговая оценка вероятности в статье на 2% ниже.
поэтому и итоговая оценка вероятности в статье на 2% ниже.

Да, мне кажется, справедливое замечание.
скажем мы реализуем лото "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

Sign up to leave a comment.

Articles