Как мы можем сгенерировать несколько случайных чисел в эфириуме?

Я хочу, чтобы мой смарт-контракт возвращал 7 или 8 УНИКАЛЬНЫХ случайных чисел в диапазоне от 1 до 100 при вызове контракта. Как лучше всего добиться такого результата?


person Joe Mutti    schedule 23.09.2018    source источник
comment
Зависит от того, для чего вы хотите его использовать, но рандомизация в блокчейне сложна, используйте оракул.   -  person Raghav Sood    schedule 23.09.2018
comment
Oracle для чего? Я работаю над смарт-контрактом, чтобы просто возвращать только случайные числа и ничего больше. Как я могу этого добиться?   -  person Joe Mutti    schedule 23.09.2018


Ответы (4)


Вероятно, если вы пытаетесь создать рулетки, лотереи и карточные игры с использованием блокчейна Ethereum, поскольку блокчейн Ethereum является детерминированным, он создает определенные трудности для тех, кто решил написать свой собственный генератор псевдослучайных чисел (PRNG).

Некоторые используемые в настоящее время уязвимые методы

Если вы используете переменные блока, такие как block.coinbase, block.difficulty, block.timestamp и т. Д., В качестве источника энтропии, все эти переменные блока могут управляться майнерами, поэтому они не могут использоваться в качестве источника энтропии из-за поощрение майнеров. Поскольку переменные блока, очевидно, используются совместно в одном блоке, вы можете легко использовать внутренние сообщения для получения того же результата.

Другие методы похожи на использование блочного хэша текущего или некоторого прошлого блока или блочного хэша прошлого блока в сочетании с частным начальным значением. В этих случаях используется функция block.blockhash (block.number). Однако в момент выполнения транзакции в EVM хэш создаваемого блока еще не известен по очевидным причинам, и EVM всегда будет давать ноль. Если мы пробуем это с хешем предыдущего блока, злоумышленник может заключить контракт эксплойта с тем же кодом, чтобы вызвать целевой контракт через внутреннее сообщение. «Случайные» числа для двух контрактов будут одинаковыми.

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

Некоторые области, которые стоит изучить

  • Внешние оракулы
  • Сигнидице
  • Фиксировать – раскрыть подход

С помощью внешних оракулов, таких как Oraclize, смарт-контракты могут запрашивать данные из веб-API, такие как курсы обмена валют, прогнозы погоды и цены на акции (например, random.org). Ключевой недостаток этого подхода - централизация. Будет ли демон Oraclize вмешиваться в результаты? Можем ли мы доверять random.org?

Вместо Oraclize мы также можем использовать BTCRelay, который является мостом между блокчейнами Ethereum и Bitcoin. Используя BTCRelay, смарт-контракты в блокчейне Ethereum могут запрашивать будущие хэши биткойнов и использовать их в качестве источника энтропии.

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

  • Игрок делает ставку, вызывая смарт-контракт.
  • Дом видит ставку, подписывает ее своим закрытым ключом и отправляет подпись в смарт-контракт.
  • Смарт-контракт проверяет подпись с помощью известного открытого ключа.
  • Затем эта подпись используется для генерации случайного числа.

Подход «фиксация – раскрытие» состоит из двух этапов:

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

Лучшая реализация подхода «фиксация-раскрытие» - Randao. Фиксация – раскрытие может быть объединена с будущими хешами блоков, чтобы сделать его более безопасным.

Это в значительной степени охватывает все методы генерации случайных чисел с использованием Ethereum.

person Joseph T F    schedule 24.09.2018

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

С учетом сказанного, одним из лучших решений является использование оракула, который получает случайное число из внешнего (читай: не основанного на блокчейне) источника. Взгляните на это гид. Ethtroll Dapp является хорошим примером этого, поэтому взгляните на код здесь. Они используют Oraclize для получения случайного числа с Random.org.

Проблема с использованием оракула - фактор централизации. Если вы настроите свое Dapp так, как я описал выше, вы окажетесь во власти румян двух разных централизованных служб - Oraclize и Random.org. Хотя маловероятно, что кто-то сможет манипулировать любым из этих источников, люди будут совершать иррациональные действия ради потенциальной экономической выгоды.

person Shane Fontaine    schedule 23.09.2018

Используйте Chainlink VRF.

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

У вас должна быть сеть оракулов, которая может:

  1. Докажите, что генерируемые числа случайны.
  2. Имейте достаточно оракулов / узлов, и даже если один из них выйдет из строя / поврежден, ваш смарт-контракт сохранится.

На этот раз в приведенном ниже примере показано, как решить №1. Вы можете решить №2, подключившись к достаточному количеству узлов, поддерживающих Chainlink VRF.

Чтобы узнать точную реализацию, см. Этот ответ из аналогичного вопроса.

Вы захотите сделать запрос к узлу с функцией, которая принимает сгенерированное вами семя:

 function rollDice(uint256 userProvidedSeed) public returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) > fee, "Not enough LINK - fill contract with faucet");
        uint256 seed = uint256(keccak256(abi.encode(userProvidedSeed, blockhash(block.number)))); // Hash user seed and blockhash
        bytes32 _requestId = requestRandomness(keyHash, fee, seed);
        emit RequestRandomness(_requestId, keyHash, seed);
        return _requestId;
    }

И когда значение будет возвращено, вы измените его на 100 и прибавите 1. Вам нужно будет вызвать это 7 или 8 раз, если вы хотите 7 или 8 случайных чисел.

function fulfillRandomness(bytes32 requestId, uint256 randomness) external override {
        uint256 d6Result = randomness.mod(100).add(1);
        emit RequestRandomnessFulfilled(requestId, randomness);
    }

person Patrick Collins    schedule 22.05.2020

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

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

Сначала я совершаю коммит (лотерея Алисы) в smartContract. Если заголовок повторяется (проверьте хеши), он будет отклонен. И для раскрытия потребуется дождаться подтверждения хотя бы одного дополнительного блока, эти 2 блока должны поступать от разных майнеров, чтобы гарантировать, что майнер не атакует этот смарт-контракт.

И затем вы выполняете Reveal (лотерея Альберто). Здесь происходит волшебство; Источниками для random будут заголовок, msg.sender, block.blockhash блока фиксации и block.blockhash (commitBlockNumber + 1), потому что никто не может предсказать будущий хэш, ни какой майнер его обнаружит [вы можете добавить coinbase или отметка времени также, чтобы получить больше случайного значения]. Также вы можете проверить, слишком ли близки или слишком разделены временные метки commitBlockNumber и commitBlockNumber + 1, это может указывать на то, что какой-то майнер пытается принудительно заблокировать какой-то блок, поэтому вы можете отклонить эту лотерею.

И, конечно, если вы можете наблюдать слишком много близких транзакций с помощью коммитов вроде (Лотерея Алисы) || (A Лотерея Алисы) вы можете проверить, обманывают ли эту лотерею. Также вы можете сделать это с более чем 2-мя интервалами.

person Alberto Perez    schedule 24.10.2020