ZYCORD docs
Русский

Майнинг

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

Всё, что нужно#

# A payout address. The node never sees the key behind it.
zcd wallet new --out miner.json

# Mine to it.
zycordd --testnet --dir ./testnet \
  --mine --payout $(zcd wallet address --key miner.json | awk '/^persistent/ {print $3}')

zcd wallet address печатает две строки: следующий неиспользованный одноразовый адрес и постоянный; для выплаты нужен постоянный. В публичном testnet и в mainnet zcd и zycordd являются бинарниками -randomx — zcd-randomx и zycordd-randomx. Бинарник, собранный без этого тега, отказывается запускаться, а не откатывается к отладочному движку. См. Установка.

Запускайте когда угодно#

Узел, запущенный до срока первого блока своей сети, не майнит раньше времени и не требует повторного запуска в назначенный час. Он отказывается строить блок, до метки времени которого не дошли его собственные часы, ждёт и начинает сам. Пока он ждёт, он сообщает об этом, называя время, которого ждёт, и сколько осталось:

waiting to mine: the next block cannot be dated before 2026-10-07T00:00:01Z
(unix 1791331201), and this node's clock reads 2026-10-06T20:12:31Z - 3h47m30s
to wait. Leave this running: mining starts on its own and there is nothing to
restart or reconfigure.

Это отказ майнить, а не отказ работать: узел всё это время поддерживает пиринг, синхронизируется и обслуживает свой RPC. Сообщение повторяется каждые десять минут, чтобы долгое ожидание не выглядело зависанием.

Если он никогда не перестаёт это говорить, у вас неверные часы

Ожидание считается по часам этой машины, поэтому часы, отставшие на дни, будут ждать дни. Проверьте их прежде всего остального.

Этот отказ — ещё и причина, по которой вообще безопасно публиковать время старта. Без него майнер датировал свой заголовок вперёд, до медианного нижнего предела, которым до генезис-блока является сам genesis_time — так что ранний старт порождал приватную цепочку, о которой никто другой не мог судить, и, поскольку правило сложности измеряет заявленные времена решений, цепочку, чья цель ужесточалась каждым блоком по интервалам, не имевшим ничего общего с реально прошедшим временем. Никому не нужно было быть нечестным ради этого; так раньше вело себя то, что оставили работать на ночь.

Адрес выплат должен быть постоянным#

Это обязан быть постоянный (0x02) адрес — строка persistent в выводе zcd wallet address — и zycordd отвергает любой другой, а не предупреждает. Это правило узла, а не консенсуса: цепочка заплатила бы и на одноразовый адрес, а блок ниже объясняет, почему это плохая идея. Узел никогда не видит ключ, который управляет выплатой, и не смог бы потратить вознаграждение, даже если бы захотел.

Почему одноразовый адрес выплат молча теряет деньги

Одноразовый (0x01) адрес выплат майнит правильно ровно до того момента, как вы один раз с него потратите. Это списание помечает адрес израсходованным навсегда, и свёртка сжигает каждое созревающее вознаграждение, адресованное ему, начиная с того же блока — кольцо созревания проворачивается после того, как сертификаты блока лягут, так что блок, несущий трату, уже становится первым блоком, теряющим деньги, и вместе с ним уходит всё, что от ваших последних coinbase_maturity блоков ещё осталось в кольце.

Никаких ошибок при этом не возникает. Единственный след — на собственной строке блока этого узла: matured=0, что печатается и при обычном пустом слоте кольца, и burned=, который тихо вобрал всю долю производителя вместе с базовой комиссией и комиссией за пропуск, о которых он обычно и сообщает. Ни одно из полей не говорит «coinbase». Постоянный адрес вообще не может попасть в реестр израсходованных, поэтому отказ устранён, а не сужен — см. правило кошелька 3.

Созревание coinbase#

Вознаграждения созревают через coinbase_maturity блоков — 240 в mainnet (около двух часов) и 100 в публичном testnet. До этого они видны в состоянии, но их нельзя потратить, и именно они дают первые депозиты в цепочке без премайна: примерно первые два часа mainnet транзакции могли совершать только майнеры.

Само вознаграждение начинается с малого. За первые 30 дней (до высоты 86 400) субсидия блока линейно растёт от почти нуля до полного расписания, и из каждой субсидии 94% получает майнер, 3% — основатель в течение трёх лет и 3% — казна. Комиссии никогда не делятся: базовые комиссии сжигаются, а приоритетные комиссии применённых сертификатов достаются майнеру. Расписание после разгона описано в разделе Эмиссия; zcd emission --height N печатает субсидию и её распределение на любой высоте.

В mainnet нет крана и не будет, поэтому в mainnet этот разгон и есть всё распределение: майни, чтобы играть. У публичного testnet кран есть, и он, как и всё остальное в этой сети, пополняется майнингом, потому что сеть, монеты которой ничего не стоят, ничего не теряет, позволяя кому-то отрепетировать кошелёк прежде, чем репетировать майнер.

Во что обходится запуск#

Рабочая функция — это параметр консенсуса, а не настройка. zcd params её печатает:

proof of work    randomx-v2 (re-keyed every 2048 blocks, 64-block lag)

Память#

Проверке нужно около 256 МиБ на каждую удерживаемую эпоху ключа, а таблица держит две, чтобы реорганизация через границу ключа не вызывала перестроение на каждом блоке. Закладывайте больше, чем эта таблица, потому что предел задаёт не она. Кеш занимает память с момента выделения, а дорогое заполнение Argon2 идёт уже после — так что во время построения живыми могут быть ещё до двух — а запись, вытесненная, пока ею ещё кто-то пользуется, удерживает всё, что имеет, пока этот пользователь её не отпустит, а именно так ведёт себя майнер во время заполнения набора данных.

РольБюджетПочему
Проверяющий узел~1 ГиБ на движокПиковый кеш при таблице из двух записей был измерен в 1280 МиБ при обоих эффектах разом — а не 512 МиБ, как подсказывает таблица.
Майнящий узел~3,3 ГиБДополнительно выделяет набор данных на ~2 ГиБ и является тем случаем, который удерживает заимствующего на всё время заполнения.

Машина, способная спокойно проверять, не обязательно способна майнить.

Потоки#

--mine-threads по умолчанию равен одному на ядро. На действительность он не влияет никак; это лишь то, насколько быстро этот узел ищет решение.

Что происходит при смене ключа#

Рабочей функции задаётся новый ключ каждые randomx_key_interval блоков. Майнящий узел перестраивает тогда набор данных на ~2 ГиБ и на это время перестаёт майнить — порядка десяти секунд, зависит от машины; измерьте на своей от первой границы в журнале.

Проверять он при этом не прекращает, и перестроение не может его застопорить: заголовок из любой эпохи ключа, кроме той, в которой идёт майнинг, проверяется на собственном кеше этой эпохи в 256 МиБ, которого набор данных не касается. Оба вычисляют одинаковые дайджесты, так что единственное, на что перестроение влияет в проверке, — это скорость. Кеш следующей эпохи прогревается за последние randomx_key_lag блоков эпохи.

Сетьrandomx_key_intervalПауза в майнинге, примерно
mainnet2048 блоководна раз в ~17 часов
публичный testnet512 блоководна раз в ~4 часа

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

Остановка майнящего узла#

SIGTERM (или Ctrl-C) его останавливает, и останавливает без промедления: один сигнал доходит до каждого цикла, а не до того, который случайно оказался ждущим на канале.

Остановка, пришедшаяся на смену ключа, дожидается окончания заполнения набора данных — движок не отпустит буфер на ~2 ГиБ, пока вызовы хеширования всё ещё из него читают, а это обращение к освобождённой памяти в C, о котором никакой инструментарий Go не сообщил бы. Это остановка, ждущая фиксированного события, а не гоняющаяся с ним: по измерениям на десяти запусках момент выхода не сдвигался, как бы рано ни приходил сигнал, тогда как ожидание сокращалось с 4,5 с до 0,7 с, без единого SIGSEGV.

Поэтому закладывайте таймаут остановки больше, чем время заполнения на вашей машине. Второй SIGTERM не ждёт — первый возвращает обработку сигнала операционной системе, так что повторное нажатие Ctrl-C во время этой паузы немедленно убивает процесс.

Пулы и почему их нет#

Проект не управляет ни одним пулом и не одобряет ни один. Узел майнит соло сразу после установки, а с --stratum-listen он обслуживает диалект Stratum, который понимает стандартный XMRig, так что внешнее майнинговое ПО может работать с вашим собственным узлом. Этот сокет не аутентифицируется — любой, кто может до него достучаться, может майнить через ваш узел на собственную выплату — поэтому привязывайте его к loopback или к сети, которой доверяете. Если пулы появятся, это будут третьи стороны; относитесь к ним с тем же скептицизмом, что и везде.

Ботнеты, названные, а не отрицаемые#

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

Наблюдение за работой#

Обозреватель testnet отображает каждый блок и каждый сертификат, включая ту страницу, которую не может отобразить обозреватель ни одной другой цепочки: был ли каждый сертификат применён или пропущен со списанием, и какое заявленное чтение перестало выполняться. Ваш собственный узел отвечает на те же вопросы на /status, /head и /metrics — см. поверхность только для чтения.