ZYCORD 文档
简体中文
Zycord文档挖矿

挖矿

用 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)

在公共 testnet 和 mainnet 上,那指的是 -randomx 二进制文件 — zcd-randomx 和 zycordd-randomx。一个不带该标签构建出的二进制文件会 拒绝启动,而不会回退到开发用引擎。请看 安装。

你想什么时候启动都行#

一个在其网络的首个区块到期之前就启动的节点不会提前挖矿,也不需要到点再启动一次。 它会拒绝构建一个时间戳尚未被自己时钟走到的区块,等待,然后自行开始。它在等待期间会这么说, 并给出它在等的那个时间以及还剩多久:

waiting to mine: the next block cannot be dated before 2026-10-01T00:00:01Z
(unix 1790812801), and this node's clock reads 2026-09-30T20: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)地址 — zcd wallet address 默认就打印一个 — 而 zycordd 会拒绝其他任何 类型,而不是只给个警告。节点从来看不到控制它的那把密钥,就算它想花掉那笔奖励也做不到。

为什么用一次性地址收款会不声不响地亏钱

一个一次性(0x01)收款地址一直都能正常挖矿,直到你从它那里花出去一次为止。 那次借记会永久地把该地址标记为已花费,而从同一个区块起,折叠会烧掉每一笔寄往它的、正在成熟的奖励 — 成熟环是在该区块的凭证落定之后才滚动的,所以携带这笔花费的那个区块本身就已经是第一个亏钱的区块, 而你最近 coinbase_maturity 个区块中仍留在环里的部分也会一并陪葬。

什么错误都不会报。唯一的痕迹在那个节点自己的区块日志行上: matured=0,而这也正是一个普通的空成熟环槽位会打印的东西;还有一个 burned=,它已经悄悄把整份生产者份额连同它平常会报告的基础费和 跳过费一起吸收了进去。这两个字段都没有说“coinbase”。持久地址根本不可能进入 已花费注册表,所以这个失败是被消除掉的,而不只是被收窄 — 请看 钱包规则 3。

Coinbase 成熟期#

奖励在 coinbase_maturity 个区块之后成熟 — 在 mainnet 和公共 testnet 上 都是 100。在那之前它们在状态中可见但不可花费,而这正是在一条没有预挖的链上为最初那些保证金 提供资金的东西:在大约头一百个区块里,只有矿工能进行交易。

Mainnet 没有水龙头,将来也不会有,所以在 mainnet 上,那段爬坡就是 分配的全部:想玩就得挖。公共 testnet 有 一个水龙头,它和上面其他一切一样由挖矿供资,因为一个 币毫无价值的网络,让人在预演矿工之前先预演一下钱包,什么也不会损失。

运行它的开销#

工作函数是一个共识参数,不是一项设置。zcd params 会打印它:

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

内存#

验证大约需要每持有一个密钥纪元 256 MiB,而这张表会持有两个,好让跨越密钥边界的 一次重组不至于每个区块都重建一次。预算要比这张表更宽裕,因为这张表并不是上界。 一份缓存从被分配的那一刻起就常驻内存,而让它昂贵的那次 Argon2 填充是在之后才发生的 — 所以在构建期间最多还会有另外两份是活的 — 而一个在仍有东西在用它时被逐出的条目, 会一直保留它所持有的一切,直到那个使用者放手为止,而矿工在一次数据集填充期间做的正是这件事。

角色预算为什么
验证节点引擎约需 ~1 GiB在两条目表的情况下,两种效应同时出现时测得的缓存峰值为 1280 MiB — 而不是这张表所暗示的 512 MiB。
挖矿节点~3.3 GiB此外还要分配约 2 GiB 的数据集,而且它正是在填充期间把一个借用方钉住的那种情形。

一台能从容验证的机器未必就能挖矿。

线程#

--mine-threads 默认为每个核心一个。它对有效性没有任何影响;它决定的是这个节点 寻找一个解的速度有多快。

换密钥时会发生什么#

工作函数每 randomx_key_interval 个区块换一次密钥。挖矿节点届时会重建那份约 2 GiB 的 数据集,并在重建期间停止挖矿 — 量级在十秒左右,视机器而定;请从你日志里的第一个边界开始测量你自己的。

它在整个过程中都继续验证,而且一次重建也不会把它卡住:来自正在挖的那个密钥纪元 之外任何纪元的区块头,都会用那个纪元自己那份 256 MiB 缓存来验证,而数据集根本不碰它。两者算出的 摘要完全相同,所以一次重建对验证造成的唯一差别是速度。下一个纪元的缓存会在本纪元最后 randomx_key_lag 个区块内被预热。

网络randomx_key_interval挖矿停顿,大致
mainnet2048 个区块约每 17 小时一次
公共 testnet512 个区块约每 4 小时一次

testnet 较短的间隔是刻意的:更频繁地预演那个边界,正是这个网络存在所要测量的内容之一。 提前构建下一个纪元的数据集是可行的 — 密钥来自高度,所以远在边界之前就已知晓 — 而这件事被刻意地不去做:那意味着要同时持有两份,共 4 GiB,只为省掉一次每天让矿工付出几秒钟的停顿。

停止一个挖矿节点#

SIGTERM(或 Ctrl-C)会让它停下,而且它停得很快:一个信号 会抵达每一个循环,而不是碰巧在通道上等着的那一个。

一次落在换密钥期间的停止会等待数据集填充完成 — 在哈希调用还在读取那块约 2 GiB 的缓冲区时,引擎不会释放它,那在 C 里是一个释放后使用, 而没有哪个 Go 工具会报告它。这是一次在等待某个固定事件的停止,而不是一次与之赛跑的停止:在十次运行中测量, 无论信号来得多早,退出的时刻都没有挪动,而等待时间从 4.5 秒缩短到 0.7 秒,且没有出现 SIGSEGV。

所以请把停止超时设得高于你机器的填充时间。第二次 SIGTERM 不会等待 — 第一次会把信号交还给操作系统,所以在那次停顿期间再按一次 Ctrl-C 会立刻杀掉这个进程。

矿池,以及为什么一个都没有#

发布时一个也不存在,也没有任何官方矿池。节点开箱即可单人挖矿,而在创世 难度下这是合理的入场方式。如果出现了矿池,它们是第三方;请用你在别处会用的同样 怀疑态度对待它们。

僵尸网络,被点名而不是被否认#

CPU 挖矿会招来它们。每一种可用 CPU 挖矿的币都与它们交过手,这个项目也不指望 自己是例外。这个取舍是睁着眼睛做的:一个被僵尸网络扭曲的分配, 仍然比一个在销售中定下来的分配更广泛,而让你已经拥有的那台笔记本保持竞争力,正是 RandomX 存在的全部理由。

看着它工作#

testnet 区块浏览器会渲染每一个区块和每一份凭证, 包括那个其他任何链的区块浏览器都渲染不出的页面:每一份凭证究竟是被应用了,还是 被跳过并计费了,以及是哪一项声明的读取不再成立。你自己的节点在 /status、/head 和 /metrics 上回答同样的问题 — 请看 只读接口。