Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
ropox
8 лет назад

Рандомный блокчейн

Как и обещал, напишу как работает генератор случайных чисел основанный на блокчейне и используемый в моем @lotobot.

Все началось со статьи на habrahabr, которую я увидел благодаря @habreplicator. :) Вот тут этот перепост habreplicator.

Я уже видел на steemit лотерейного бота, работающего по примерно той же схеме. Боту перечисляется один STEEM, а через 8 часов производится розыгрыш. Только непонятно было, как там генерируется случайное число. Да и я честно говоря не вдавался в подробности.

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

  "result": {
    "previous": "004e86d48d7821f3eae7202828b51a2efc809b16",
    "timestamp": "2017-04-15T09:58:24",
    "witness": "creator",
    "transaction_merkle_root": "defcd7c3832fed805d20afa670b427c148df4dc2",
    "extensions": [],
    "witness_signature": "201dfcc2a9ed3afb215883583590dfc1d1091e8f1a86ebd60af65ba6f31a8004af482efcfe7e440772a7dc2755ac0fc1d4d0b292a7f2cbc998c033af1020238372",
    "transactions": [{

Как видно witness_signature содержит подпись делегата @creator. Это хеш сгенерированный из комбинации {содержимое блока + ключ делегата}. Так как каждый блок включает в себя сигнатуру предыдущего блока, то содержимое подписи делегата зависит так же и практически всей цепочки блоков.

Теперь если взять другой блок (на момент окончания раунда лотереи), то у него будет своя подпись, которая зависит от деятельности пользователей блокчейна. Любые посты, переводы монет, апвоты сделанные в течении раунда влияют на то, как будет выглядеть подпись делегата.

В своей лотереи пост с анонсом очередного раунда содержит permlink собранный особым образом.К примеру lottery-round-finalizer-149220678600. Где число это серверное время на момент создания очередного раунда. Таким образом по окончанию лотереи, когда 12-и часовой раунд заканчивается я без труда нахожу блок с анонсом и беру от туда подпись. А так же беру текущий блок и тоже из него беру подпись.

Обе подписи складываются и для полученного текста вычисляется keccak-256 хэш. Потом шестнадцатеричное представление хэша преобразуется в большое целое число которое в итоге делится по модулю, на число участников. Остаток от деления и есть счастливое число.

Вот так выглядит примерно вычисление в коде.

    getLuckyNumber(participantsCount) {
        let d = new hasher("keccak256");
        d.update(this.startSig + this.endSig);
        this.sha3 = d.digest().toString("hex");
        return BigInt(this.sha3, 16).mod(participantsCount).value;
    }

Для вычисления хэша и взятия по модулю я использовал npm библиотеки keccak и big-integer

Аналог я использовал для вебстраницы. Код страницы можно посмотреть на github-е здесь.

Недостатки

Пока что этот метод не идеален в том смысле, что я второй блок я выбираю случайно. На самом деле я не выбираю. А каждую минуту вызывается get_dynamic_global_parameters. Я беру от туда текущее серверное время и номер последнего блока. Если время прошедшее с начала раунда больше 12 часов, то я использую прочитанный блок в вычислениях. То-есть обладай я злым умыслом, я мог бы перебирать блоки в поисках нужного с подписью, с помощью которой я мог бы сгенерировать номер моего подставного лица.

Поэтому я думаю сейчас переделать на другой вариант. По окончании раунда будет создан пост извещающий об окончании приема ставок. Позже будут использованы подписи блока анонса раунда и блока с постом об окончании раунда. В этом случае я не смогу повлиять на результат лотереи. В этом случае только майнер сможет подобрать подпись. Только это вряд ли, так как майнеров несколько, неизвестно кому выпадет счастье подписывать именно тот блок, с постом @lotobot. Да и подобрать надо хеш за очень малое время.

12
312.682 GOLOS
На Golos с February 2017
Комментарии (0)
Сортировать по:
Сначала старые