Как я могу безопасно генерировать случайное число в моем смарт-контракте?

Если я пишу умный контракт на какую-то игру (азартную игру), как я могу безопасно создать случайное число? Каковы наилучшие методы и компромиссы с безопасностью, о которых нужно знать?

121 голос | спросил Joris Bontje 21 Jam1000000amThu, 21 Jan 2016 09:56:26 +030016 2016, 09:56:26

13 ответов


97

В этой области есть несколько компромиссов и ключевых моментов.

  1. Любое решение, которое пользователь делает, которое влияет на результат, дает этому пользователю несправедливое преимущество. Примеры включают:

    1. Использование блочного изображения, метки времени или другого значения, заданного шахтером. Имейте в виду, что у шахтера есть выбор: публиковать блок или нет, поэтому у них может быть один шанс на выигрыш за каждый блок, который они имеют.
    2. Любое случайное число, отправленное пользователем. Даже если пользователь предварительно фиксирует число, у них есть выбор: показывать или не показывать номер.
  2. Все, что видит контракт, видит общественность.

    • Это означает, что номер не должен генерироваться до тех пор, пока вход в лотерею не будет закрыт.
  3. EVM не будет превосходить физический компьютер.

    • Любое число, которое создает контракт, может быть известно до конца этого блока. Оставьте время между генерацией номера и его использованием.

Теперь для техники:

Совершенно децентрализованное неприемлемое обязательство лотерейного стиля:

  1. Казино отменяет вознаграждение за случайное число.
  2. Каждый пользователь генерирует свое собственное секретное случайное число N
  3. Пользователи создают свое обязательство путем хэширования их N с их адресом: bytes32 hash = sha3(N,msg.sender) 1
    • примечание: шаги 2 и amp; 3 следует выполнять локально, в тайне
  4. Пользователи отправляют свой хэш в контракт, вместе с эфиром, большим или равным по значению, для значения случайного числа. 2
  5. Материалы продолжаются для некоторого количества блоков или до тех пор, пока не будут присоединены достаточные участники.

    Как только раунд подачи завершен, начинается раунд открытия.

  6. Каждый пользователь отправляет свое случайное число N в контракт

  7. Контракт подтверждает, что sha3(N,msg.sender) соответствует исходному представлению

    • Если пользователь не отправит действительный N вовремя, его депозит будет лишен.
  8. N s - все XOR 'd вместе для генерации полученного случайного числа.

  9. Этот номер используется для определения того, кто из участников получает награду. (N % numUsers) 3

Примечания и альтернативы:

1. Пользователи должны объединить свой адрес с их кодом N перед хэшированием. В противном случае другой пользователь может просто отправить идентичный хеш, а затем ждать появления N, а затем отправить его. N XOR N равно 0, поэтому это можно использовать для отмены всех представлений, кроме злоумышленника.

2. Это место, где появляются компромиссы. У последнего, кто раскрывает свой N, есть выбор: показывать или не раскрывать. Это, по сути, дает им двойной шанс на победу. Введите достаточно времени, и вы получите новый выбор для каждой записи. Подсказка: майнеры выбрали порядок транзакций в блоке. Чтобы отговорить это, пользователи должны установить большой депозит безопасности, равный значению, которое они получат, манипулируя случайным числом. Это может быть проблемой для многих пользователей, особенно для больших джекпотов, даже с оптимизацией игры.

  • Обычно используемой альтернативой является полуцентрализованная система. Это требует, чтобы «дом» подал первый хэш и последний раз. Если дом не выполняет свой долг, возвращается каждый эфир. У этого есть проблемы, такие как дом, выбирающий чешуйку, если ожидается выплата джекпота. Идея заключается в том, что на карту поставлена ​​репутация дома.
    • Обратите внимание, что это по существу централизует всю систему. Просто нужно снять дом, чтобы вся операция была отключена. Этот риск может быть уменьшен путем найма нескольких доверенных не-игроков для первого /последнего участника.
  • Другой трюк заключается в том, чтобы использовать нанятых профессиональных третьих сторон для «разминирования» случайности для вас, чтобы игроки не нуждались в этом процессе.

3. Для поощрения конкуренции между участниками необходима награда. Это вызывает классическую ситуацию с дилеммой, связанной с трагедией /компромиссом /заключенным. Сговор между участниками позволит им выиграть большой банк и разделить его между собой, но если все знают, что подарят все остальные, они знают, что они сами должны подать, чтобы выиграть награду. Таким образом, если вознаграждение больше, чем значение случайного числа, деленное на количество игроков, то каждый из них заинтересован в том, чтобы сохранить свой номер в тайне, чтобы лучше выстрелить в награду. Обратите внимание, что только один из участников должен представить хорошее случайное число, и результат будет непредсказуемым.

Примеры: RANDAO , Тема, в которой я впервые подумал через это

ответил Tjaden Hess 21 Jam1000000amThu, 21 Jan 2016 11:12:49 +030016 2016, 11:12:49
18

Обратите внимание, что с предложением Linagee вы не просто доверяете random.org, но и доверяете Oraclize. Oraclize опубликуйте нотариальное доказательство TLS, чтобы показать, что данные, которые они вам дают, действительно пришли из random.org, но этого недостаточно для этого случая: нам нужно знать, что это были только данные only от random.org. В противном случае они могли продолжать пытаться и отбрасывать случайные числа с random.org, пока не получили тот, который выиграл свою ставку, и вы не сможете обнаружить это.

ответил Edmund Edgar 29 FebruaryEurope/MoscowbMon, 29 Feb 2016 03:42:43 +0300000000amMon, 29 Feb 2016 03:42:43 +030016 2016, 03:42:43
12

Вы можете использовать https://api.random.org/json-rpc/1/, который дает вам случайный источник данных через JSON и Oraclize, который позволяет вам использовать фид внутри контракта Ethereum и, возможно, он сильно аутентифицирован как имеющий случайный сайт. (Наряду с существующими методами использования хэша блока, временной метки и т. Д.)

Вы будете «доверять» random.org, чтобы передавать вам случайные данные. Вы можете уменьшить риск, используя несколько источников случайности.

ответил linagee 21 Jam1000000amThu, 21 Jan 2016 11:38:13 +030016 2016, 11:38:13
6

Короткий ответ: вы не можете. RANDAO работает, но он медленный, и если ваша игра популярна, у людей будет сильный стимул для игры с последним номером.

Я предлагаю использовать оракул для обеспечения случайности. (как упоминалось в заметках и альтернативах Тьядена Хесса 2c). Два основных преимущества: вы можете решительно утверждать, что ваш номер не зависит от какой-либо другой ставки, что жизненно важно для оценки риска использования этого числа. Во-вторых, фактически нет предела пропускной способности энтропии. Если есть рынок оракулов, то вы можете использовать безотзывную историю блочной цепи, чтобы моделировать вероятность того, что данный оракул сговорит с игроками или нет. Конечно, игроки, дом и оракул все обеспечивают свою собственную энтропию. Другие функции, такие как «белый список», «черный список», облигации, подтверждающие неконтактность и т. Д. И т. Д., Могут быть добавлены по желанию.

ответил A. Frederick Dudley 5 FebruaryEurope/MoscowbFri, 05 Feb 2016 20:58:28 +0300000000pmFri, 05 Feb 2016 20:58:28 +030016 2016, 20:58:28
6

Так как разные контракты , обеспечивающие разные значения значения , на противоположном конце спектра RANDAO является простым BLOCKHASH .

Если BLOCKHASH может соответствовать вашей цели, настоятельно рекомендуется рассмотреть вопрос (ниже всего фрагмент):

Когда BLOCKHASH можно безопасно использовать для случайного числа? Когда это будет небезопасно?

  

Как правило, BLOCKHASH можно безопасно использовать только для случайного   номер, если общая сумма стоимости зависит от качества этого   случайность ниже того, что зарабатывает шахтер, добывая один блок.

ответил eth 22 FebruaryEurope/MoscowbMon, 22 Feb 2016 22:39:09 +0300000000pmMon, 22 Feb 2016 22:39:09 +030016 2016, 22:39:09
3

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

Почему бы просто не повернуть вещь на свою сторону и просто не включать контракт вообще в процесс генерации случайных чисел?

Игра в лотерею может работать следующим образом:

  • Каждый игрок представляет транзакцию в лотерейный договор, содержащий плату, желаемый «выбранный» номер и зашифрованное случайное начальное значение. Если тот же игрок хочет выбрать другой номер, требуется только сбор и выбор - семя - за игрока, а не за ставку.

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

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

Здесь много ручных и левых деталей, но я считаю, что основная идея звучит.

ответил jimkberry 12 Mayam16 2016, 06:56:29
1

Давайте подумаем, что вы используете хеш-блок, чтобы определить победителя лотереи, а шахтер А участвует в этой лотерее и покупает один билет. Затем он уничтожает много действительных блоков и отбрасывает их, если они не подходят для его билета.

На практике каждый действительный блок, который выбрасывает шахтер, стоит ему 5 эфиров. Если шансы вашей лотереи таковы, что шахтер А должен, например, создать 1 000 000 действительных блоков, пока не найдет подходящий блок для победы, он выбросит 5 000 000 эфиров.

Если основной выигрыш вашей лотереи составляет 1 000 000 эфиров, для майнера не имеет смысла выбрасывать 5 000 000 эт, чтобы выиграть 1 000 000.

ответил Matias 15 MaramTue, 15 Mar 2016 11:22:00 +03002016-03-15T11:22:00+03:0011 2016, 11:22:00
1

У меня есть идея, которая основывается на протоколе Тьядена, который я описываю здесь:

Этот подход к эфирную лотерею и /или роман?

Решает проблему наличия большого депозита безопасности в лотереях. Поблагодарили бы за отзыв.

ответил EthJ 28 MaramTue, 28 Mar 2017 10:03:01 +03002017-03-28T10:03:01+03:0010 2017, 10:03:01
0

Как насчет этого потока:

1) Каждый пользователь генерирует строку «Я являюсь частью лотереи, а мой номер - 8272143» (секретно), где 8272143 является выбранным мной номером.

2) Каждый пользователь шифрует свою собственную строку с помощью собственного пароля (секретного)

3) Каждый пользователь публикует зашифрованную строку, поэтому теперь все могут видеть все зашифрованные строки

4) Когда решено не допускать больше участников, все пользователи публикуют свои собственные пароли, и все строки дешифруются. Пользователи, которые не публикуют свои пароли, не могут быть выиграны.

5) Каждый может подтвердить, что каждый игрок говорит правду об их пароле, так как первая часть строки должна быть «Я - часть лотереи, а мой номер», поэтому нет способа подделать другой номер на данный момент.

6) Все строки теперь объединены и генерируется хеш. Этот хеш является конечным случайным числом! В случае лотереи вы можете выбрать номер, наиболее близкий к хэшу, но это всего лишь конкретная информация.

Таким образом, блокировка блоков не будет завершена. Только грубое форсирование расшифровки строк позволит получить преимущество. Этого можно избежать, используя достаточно сильное шифрование.

(Я полный новичок в этой области, так голый со мной, если это просто абсурд.)

UPDATE:

Я понимаю, что если 2 клиента работают вместе, последний клиент может подождать, пока он будет опубликовать свой пароль, и будет исключен, если его друг победит таким образом. Решением может быть то, что у всех пользователей есть количество ETH на линии, которую им придется заплатить, они не публикуют свой пароль. В целом, это решение не очень сексуально, я признаю.

ответил Stephan Ryer 1 J0000006Europe/Moscow 2017, 10:32:59
0

Марко из Oraclize здесь. Вы можете использовать Oraclize Random Data Source, который использует Ledger Trusted Execution Environment.

Вы можете прочитать введение здесь и некоторые примеры здесь .

Источник случайных данных значительно безопаснее, чем использование Random.org с TLSNotary и использование блочного сигнала для определения случайного числа, и это менее сложно и дорого, чем другие схемы выявления сбоев.

ответил Marco Giglio 11 +03002017-10-11T13:06:49+03:00312017bEurope/MoscowWed, 11 Oct 2017 13:06:49 +0300 2017, 13:06:49
0

Другой способ генерации случайных чисел может состоять в том, чтобы распределить различные источники случайности в платформу, чтобы засеять выигрышный билет. Например, мы могли бы использовать центы цен закрытия всех акций, торгуемых на основных фондовых биржах мира. Было бы почти невозможно заставить все фондовые биржи работать вместе, чтобы нарушить лото.

Цены закрытия показываются различными службами, включая Yahoo, Google, Bloomberg и т. д., поэтому они могут работать как своего рода публичная книга, чтобы проверить правильность цен.

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

ответил awavi 17 +03002017-10-17T21:34:06+03:00312017bEurope/MoscowTue, 17 Oct 2017 21:34:06 +0300 2017, 21:34:06
0

Попробуйте использовать следующий алгоритм для предотвращения обмана.

Идея состоит в том, чтобы использовать хэш блока, но номер блока не известен шахтерам /участникам и организаторам, чтобы предотвратить обман.

  1. В начале организатор определяет случайный ключ uint64 - , который будет использоваться при вычислении случайных чисел победителя. Номер uint достаточно велик и известен организатору только при запуске.
  2. Организатор исправляет номер ключа , предоставляя хэш суммы - число плюс текущий хэш блока (как соль). Хэш ключа хранится в лотерейном контракте и доступен для всех участников. Тогда хеш-ключ используется для предотвращения обмана организаторов и исправления номера ключа.
  3. Участники покупают билеты, а лотерейный договор хранит все адреса участников. Адреса также используются для расчета победителя.
  4. Когда выполняются условия (например, все билеты продаются или необходимое количество блоков генерируется или только через некоторое время), организатор начинает расчеты победителя.
  5. Организатор предоставляет сохраненный номер ключа и подтверждает, что число точно такое же, вычисляя хэш ключа (введенный в init).
  6. К сумме адресов добавляется номер ключа , и мы получили mod 255 суммы, чтобы определить количество блоков, хэш которых используется для обнаружения победителя. Номер ключа + адрес1 + адрес2 ... + адресN% 255 = номер блока победителя (хеш блока используется для получения номера победителя)

Для человека, который хочет угадать выигрышный номер, невозможно получить номер - в контракте мы имеем только хеш числа. Число довольно большое uint64 (или может быть даже больше), чтобы предотвратить «развязывание» номера. Для организаторов номер фиксирован и бесполезен, потому что все адреса владельцев билетов должны быть известны для расчета победителя.

мнения? Любые дыры в логике?

Я создал отдельный вопрос , но он здесь можно также ответить.

ответил StanislavL 5 Jpm1000000pmFri, 05 Jan 2018 12:05:40 +030018 2018, 12:05:40
0

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

Контрактные учетные записи только выполняют операцию, когда ей дается указание на Внешнюю Собственную учетную запись. Таким образом, невозможно, чтобы Контрактная учетная запись выполняла собственные операции, такие как генерация случайных чисел или API-вызовы, - она ​​может делать это только в том случае, если она запрашивается Внешней собственностью. Это связано с тем, что Ethereum требует, чтобы узлы могли согласовать результаты вычислений, что требует гарантии строго детерминированного исполнения.

подробнее: http: //ethdocs.org/en/latest/introduction/what-is-ethereum.html#how-does-ethereum-work

ответил Gabriel Vasile 22 J000000Sunday18 2018, 01:06:50

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132