Добыча (Майнинг)

Mikhail Savenkov
6 min readMar 30, 2022

До сих пор мы рассмотрели структуру блокчейна Iron Fish; этот раздел будет посвящен тому, как блокчейн Iron Fish пополняется новыми блоками. Обратите внимание, что мы используем термины “узлы” и “пиры” как взаимозаменяемые; узел в Iron Fish — это всегда пир. Несколько других кратких определений:

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

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

Чтобы стать майнером, узел должен синхронизировать обе глобальные структуры данных (дерево Меркла нот и дерево Меркла нуллификаторов) и знать как минимум два последних блока.

Создание блока

Как мы уже говорили, блок состоит из заголовка блока и тела блока. Тело блока — это просто список из 0 или более транзакций; блок, не содержащий транзакций, называется пустым блоком. Процесс создания блока одинаков независимо от того, есть ли в блоке транзакции или нет:

  1. Определите тело блока
    2. Установить сложность и цель
    3. Включите вознаграждение майнера на основе графика эмиссии монет
    4. Постройте заголовок блока

Определите тело блока

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

Блок с недействительной транзакцией будет отклонен другими узлами, поэтому перед включением его в тело блока майнер должен сначала проверить эту транзакцию (подробнее о проверке транзакций в разделе “Создание транзакций”).

Установите сложность и цель для блока

Сложность
Целевое время для блока “Железная рыба” в настоящее время установлено на 60 секунд. Это значение может быть изменено.
Цель сложности проста. При необходимости она корректируется в каждом блоке, чтобы усложнить или облегчить майнерам добычу блоков таким образом, чтобы новые блоки добавлялись в блокчейн каждые 55–65 секунд (в среднем 60 секунд). Если сеть (например, все узлы сети) не произвела блок в течение более 65 секунд, сложность предстоящего блока снижается (по сравнению со сложностью предыдущего блока). И наоборот, если майнер хочет произвести блок менее чем за 55 секунд, сложность блока с этой временной меткой будет выше, чем у предыдущего блока.
Расчет сложности Iron Fish во многом повторяет расчет сложности Ethereum, описанный в EIP-2, с некоторыми отличиями.
Чтобы определить сложность предстоящего блока, мы сначала вычисляем “ведро времени”, к которому принадлежит блок. Временное “ведро” определяется как расстояние (в интервалах по 10 секунд), на котором временная метка блока находится от желаемого диапазона от 55 до 65 секунд после предыдущего блока. Предстоящий блок, который находится через 45–55 секунд после предыдущего блока, будет иметь значение временной метки -1, блок, который находится через 35–45 секунд после предыдущего блока, будет иметь значение временной метки -2, и так далее:

Время (в секундах) после предыдущего блока___________бакет

И так далее (максимальное значение 99)

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

const diffInSeconds =
(time.getTime() — previousBlockTimestamp.getTime()) / 1000;

const difficulty =
previousBlockDifficulty -
(previousBlockDifficulty / BigInt(2048)) * BigInt(bucket);

return BigIntUtils.max(difficulty, Target.minDifficulty());

В настоящее время значение Target.minDifficulty() равно 131072, но оно может быть изменено.

Target
Мы уже обсуждали регулировку сложности для обеспечения 55–65 секунд между блоками — для этого мы регулируем цель, которая представляет собой число, под которое должен подпадать хэш блока (например, быть численно меньше цели).

Цель рассчитывается из сложности по следующей формуле: цель = 2**256 / сложность

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

Включить вознаграждение майнера на основе графика эмиссии монет

Вознаграждение за майнинг (сколько монет выделяется майнеру за успешную добычу блока) привязано к кривой эмиссии Iron Fish. Идея кривой эмиссии Iron Fish заключается в том, что после первого года после запуска сети общее количество монет увеличивается на четвертую часть от стоимости генезисного блока (за счет вознаграждения за блок). В последующие годы количество новых монет будет становиться все меньше и меньше в соответствии с функцией распада, но никогда полностью не достигнет 0.

Формула, определяющая, сколько новых монет будет отчеканено в конкретный год после запуска, такова:

Где s — начальный запас генезисного блока в 42 миллиона монет, k — коэффициент распада -.05, а x — год после запуска сети (начиная с 0).

“Год” Iron Fish в количестве блоков составляет 525 600 блоков в один календарный год (при условии 60-секундного времени блока). Мы используем приведенную выше формулу для расчета вознаграждения за блок, используя “год” Iron Fish, округленный до ближайшего .125 монеты:

Поэтому вознаграждение за блок и общее предложение в течение первых нескольких лет после запуска будут такими:

Кривая эмиссии с использованием вышеупомянутой формулы вознаграждения за блок при общем объеме предложения в 256 970 400 монет выглядела бы следующим образом:

Чтобы получить вознаграждение за успешную добычу нового блока, майнер создает специальную транзакцию miner fee в заголовке блока. Значение транзакции с вознаграждением майнера открыто, чтобы другие могли убедиться, что это именно вознаграждение за блок плюс все комиссии за транзакции, включенные в этот блок. Адрес получателя этой транзакции с вознаграждением майнера остается скрытым. Подробнее о вознаграждении майнера читайте в разделе “Создание транзакции”.

Построение заголовка блока

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

Заголовок блока состоит из следующих данных:

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

PreviousBlockHash заполняется хэшем последнего блока блокчейна в соответствии с алгоритмом хэширования Iron Fish. Это указывает на то, что данный новый блок создан на основе последнего известного блока в блокчейне.

noteCommitment Все новые заметки, включенные в тело блока, применяются (по порядку) к дереву заметок Меркла. Полученный новый корень Меркла для этого дерева и его размер (в терминах глобального количества заметок) используются для построения noteCommitment для заголовка блока.

Для построения nullifierCommitment для заголовка блока выполняется тот же процесс, но с раскрытием нуллификаторов.

Цель определяется алгоритмом сложности и цели.

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

MinersFee — это специальная транзакция для назначения вознаграждения за блок на любой адрес по выбору майнера. Стоимость этой транзакции вознаграждения за блок известна и может быть проверена, но адрес получателя скрыт. Для получения более подробной информации смотрите, как создается транзакция вознаграждения за блок (ссылка на раздел “Транзакция вознаграждения майнера” в разделе “Создание транзакций”).

Случайность представляет собой 64-битное число, такое, что при хэшировании всего содержимого заголовка блока с помощью алгоритма хэширования Iron Fish результат будет численно меньше заданного.

Алгоритм хэширования Iron Fish

Об особенностях алгоритма хэширования будет объявлено ближе к дате запуска.

--

--