Есть проблема — в децентрализованной сети сложно сгенерировать случайное число.
Практически все блокчейны уже столкнулись с этим.
Ведь в сетях, где нет доверия между пользователями, создание неоспоримого случайного числа решает множество проблем.
В этой статье мы рассказываем, как нам удалось решить проблему на примере игр.
Первым из них был Волны Рождественская елка .
Для разработки нам понадобился генератор случайных чисел.
Изначально мы планировали сгенерировать число на основе информации из блокчейна.
Однако затем стало ясно: числом можно манипулировать, а значит, решение не подходит. Мы придумали обходной путь: использовать схему фиксации-развертывания.
Сервер угадал число от 1 до 5, добавил к нему соль, а затем хэшировал результат с помощью Функции Кечака .
Сервер заранее развернул смарт-контракт с уже сохраненным номером.
Оказывается, игра сводится к тому, что пользователь угадывает число, скрытое за хешем.
Игрок делал ставку, а сервер отправлял в смарт-контракт скрытое число и «соль».
Говоря простым языком, он раскрыл карты.
После этого сервер проверял числа и решал, выиграл пользователь или проиграл.
Если сервер не отправил на проверку номер или «соль», пользователь выиграл.
В этом случае для каждой игры необходимо было заранее развернуть смарт-контракт и включить в него потенциальный выигрыш.
Это оказалось неудобно, долго и дорого.
В то время не было другого безопасного решения.
Недавно команда Tradisys предложила добавить в протокол Waves функцию rsaVerify() .
Он проверяет достоверность подписи RSA на основе открытого и закрытого ключей.
В результате эта функция была добавлена.
Мы разработали три игры: Игра в кости , Подбрасывание монеты И Кататься на волнах .
Каждый из них реализует технологию случайных чисел.
Давайте разберемся, как это работает.
Давайте рассмотрим генерацию случайного числа на примере Ride on Waves. Смарт-контракт можно найти Здесь .
Перейти на вкладку Скрипт и выберите Декомпилированный .
Вы увидите код смарт-контракта (он же скрипт).
Код смарт-контракта содержит набор функций.
Те, что отмечены как @Callable, можно запустить с помощью Транзакции вызова .
Нас интересуют две функции: делать ставку И отзывать :
- функциональная ставка (playerChoice)
- функция вывода (gameId, rsaSign)
2. Клиент создает функцию ставки.
Для изображения выше это будет ставка("50") .
3. Клиент отправляет транзакцию вызова на адрес смарт-контракта (широковещательная рассылка InvocatTx).
Транзакция содержит функцию ставки в качестве параметра вызова.
Это означает, что транзакция вызова запускает выполнение функции ставки (выбор: строка) в смарт-контракте.
4. Рассмотрим функцию ставки:
Функция записывает новую игру в состояние смарт-контракта.@Callable(i) func bet (playerChoice) = { let newGameNum = IncrementGameNum() let gameId = toBase58String(i.transactionId) let pmt = extract(i.payment) let betNotInWaves = isDefined(pmt.assetId) let feeNotInWaves = isDefined(pmt.assetId) let winAmt = ValidateBetAndDefineWinAmt(pmt.amount, playerChoice) let txIdUsed = isDefined(getString(this, gameId)) if (betNotInWaves) then throw ("Bet amount must be in Waves") else if (feeNotInWaves) then throw ("Transaction's fee must be in Waves") else if (txIdUsed) then throw ("Passed txId had been used before. Game aborted.") else { let playerPubKey58 = toBase58String(i.callerPublicKey) let gameDataStr = FormatGameDataStr(STATESUBMITTED, playerChoice, playerPubKey58, height, winAmt, "") ScriptResult(WriteSet(cons(DataEntry(RESERVATIONKEY, ValidateAndIncreaseReservedAmt(winAmt)), cons(DataEntry(GAMESCOUNTERKEY, newGameNum), cons(DataEntry(gameId, gameDataStr), nil)))), TransferSet(cons(ScriptTransfer(SERVER, COMMISSION, unit), nil))) } }
А именно:
- Уникальный идентификатор новой игры (идентификатор игры)
- Состояние игры = ОТПРАВЛЕНО
- Выбор игрока (длина сегмента 50)
- Открытый ключ
- Возможный выигрыш (в зависимости от ставки игрока)
Вот как выглядит запись данных в блокчейне (ключ-значение):
{
"type": "string",
"value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229",
"key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx"
}
«Ключ» (ключ) – идентификатор игры новая игра.
Остальные данные содержатся в строке поля «значение».
Эти записи хранятся во вкладке Данные смарт-контракт:
5. Сервер «просматривает» смарт-контракт и находит отправленную транзакцию (новую игру) с помощью API блокчейна.
Идентификатор новой игры уже записан в блокчейне, а это значит, что его больше нельзя изменить или повлиять на него.
6. Сервер генерирует функцию вывода (gameId, rsaSign).
Например, вот так: withdraw ("FwsuaaShC6DMWdSWQ5osGWtYkVbTEZrsnxqDbVx5oUpq", "base64:Gy69dKdmXUEsAmUrpoWxDLTQOGj5/qO8COA+QjyPVYTAjxXYvEESJbSiCSBRRCOAliqCWwaS161nWqoTL/TltiIvw3nKyd4RJIBNSIgEWGM1tEtNwwnRwSVHs7ToNfZ2Dvk/GgPUqLFDSjnRQpTHdHUPj9mQ8erWw0r6cJXrzfcagKg3yY/0wJ6AyIrflR35mUCK4cO7KumdvC9Mx0hr/ojlHhN732nuG8ps4CUlRw3CkNjNIajBUlyKQwpBKmmiy3yJa/QM5PLxqdppmfFS9y0sxgSlfLOgZ51xRDYuS8NViOA7c1JssH48ZtDbBT5yqzRJXs3RnmZcMDr/q0x6Bg==")
7. Сервер отправляет транзакцию вызова в смарт-контракт (широковещательная передача InvocatTx).
Транзакция содержит вызов сформированной функции вывода (gameId, rsaSign):
Функция содержит идентификатор игры новая игра и результат подписания RSA уникального идентификатора закрытым ключом.
Результат подписи не меняется.
Что это значит? Берем то же значение (идентификатор игры) и применяем к нему метод подписи RSA. Мы всегда будем получать один и тот же результат. Вот как работает алгоритм RSA. Итоговым числом манипулировать нельзя, поскольку неизвестны id игры и результат применения RSA. Выбирать номер тоже бессмысленно.
8. Блокчейн принимает транзакцию.
Он запускает функцию вывода средств (gameId, rsaSign) 9. Внутри функции вывода происходит вывод средств Функции GenerateRandInt (идентификатор игры, rsaSign).
Это генератор случайных чисел # @return 1 .
100
func GenerateRandInt (gameId,rsaSign) = {
Теги: #игры #блокчейн #Децентрализованные сети #Криптовалюты #Криптография #случайные числа #смарт-контракты
-
Хорошо Ли Спамерам Живётся На Руси...
19 Oct, 24 -
Swoopo.com Недоступен Уже Больше Недели.
19 Oct, 24 -
С Чего Начать Devops?
19 Oct, 24 -
Литдыбрь Weekend #6
19 Oct, 24 -
Генератор Брендов
19 Oct, 24 -
Об Эффективности «Упражнений» Рутрекера
19 Oct, 24 -
Навигация Изнутри
19 Oct, 24