Mineração
Proof of work com RandomX, no processador que já está no seu computador. Sem fazenda de ASIC para competir e sem premine — as moedas vêm da mineração e de mais nenhum lugar.
Tudo o que há#
# 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}')
O zcd wallet address imprime duas linhas, o próximo endereço de uso único ainda não usado e o
persistente; o pagamento vai para o persistente. Na testnet pública e na mainnet, zcd e zycordd são os binários -randomx —
zcd-randomx e zycordd-randomx. Um binário construído sem a tag se recusa
a iniciar em vez de recorrer ao motor de desenvolvimento. Veja
Instalação.
Inicie quando quiser#
Um nó iniciado antes de o primeiro bloco de sua rede estar previsto não minera cedo demais e não precisa ser iniciado de novo na hora marcada. Ele se recusa a construir um bloco cujo timestamp seu próprio relógio ainda não alcançou, espera, e começa sozinho. Ele avisa isso enquanto espera, com o horário pelo qual está esperando e quanto falta:
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.
Isso é uma recusa a minerar, não uma recusa a rodar: o nó mantém pares, sincroniza e serve seu RPC o tempo todo. A mensagem se repete a cada dez minutos para que uma espera longa não pareça um travamento.
A espera é calculada contra o relógio desta máquina, então um relógio atrasado em dias espera dias. Confira isso antes de conferir qualquer outra coisa.
Essa recusa é também o motivo pelo qual é seguro publicar um horário de início. Sem ela o minerador datava
seu cabeçalho adiante até o piso mediano, que antes da gênese é o próprio genesis_time
— então um início antecipado produzia uma cadeia privada que ninguém mais podia julgar e, como
a regra de dificuldade mede os tempos de solução declarados, uma cujo alvo endurecia a cada bloco
contra intervalos que nada tinham a ver com tempo real decorrido. Ninguém precisava ser desonesto para
isso; era o que deixá-lo rodando durante a noite costumava fazer.
O endereço de pagamento precisa ser persistente#
Ele precisa ser um endereço persistente (0x02) — a linha
persistent do zcd wallet address — e o zycordd
recusa qualquer outro em vez de avisar. Essa é uma regra do nó, não do
consenso: a cadeia pagaria a um endereço de uso único, e o quadro abaixo explica por que isso é uma má ideia.
O nó nunca vê a chave que controla o pagamento, e não poderia gastar a recompensa nem se
quisesse.
Um pagamento para endereço de uso único (0x01) minera corretamente até o momento em que você gasta a partir dele uma vez.
Esse débito marca o endereço como gasto para sempre, e o fold queima toda recompensa em maturação endereçada a
ele daquele mesmo bloco em diante — o anel de maturidade avança depois que os certificados do bloco assentam, então
o bloco que carrega o gasto já é o primeiro bloco que perde dinheiro, e o que quer que dos seus
últimos coinbase_maturity blocos ainda esteja no anel vai junto.
Nada dá erro. O único rastro está na própria linha de bloco daquele nó:
matured=0, que é também o que um slot vazio comum do anel imprime, e um
burned= que absorveu silenciosamente toda a parcela do produtor junto com as taxas base e
de omissão que ele normalmente reporta. Nenhum dos dois campos diz "coinbase". Um endereço persistente nunca pode entrar
no registro de gastos, então a falha é removida em vez de estreitada — veja
a regra 3 da carteira.
Maturidade do coinbase#
As recompensas amadurecem depois de coinbase_maturity blocos — 240 na
mainnet (umas duas horas) e 100 na testnet pública. Até lá elas ficam
visíveis no estado e não podem ser gastas, e é isso que financia os primeiros depósitos numa cadeia sem
premine: por mais ou menos as duas primeiras horas da mainnet, só mineradores conseguiam
transacionar.
A recompensa em si começa pequena. Nos primeiros 30 dias (até a altura 86.400) o
subsídio de bloco sobe em linha reta de quase zero até o cronograma cheio, e de cada subsídio
94% vão para o minerador, 3% para o fundador por três anos e 3% para a
tesouraria. As taxas nunca são divididas: as taxas base são queimadas,
e as taxas de prioridade dos certificados aplicados vão para o minerador. O cronograma depois da
rampa está em Emissão; o zcd emission --height N
imprime o subsídio e sua divisão em qualquer altura.
A mainnet não tem faucet e não terá um, então na mainnet essa rampa é toda a distribuição: minere para participar. A testnet pública tem um faucet, financiado pela mineração como todo o resto nela, porque uma rede cujas moedas não valem nada não perde nada ao deixar alguém ensaiar uma carteira antes de ensaiar um minerador.
Quanto custa rodar#
A função de trabalho é um parâmetro de consenso, não uma configuração. O zcd
params a imprime:
proof of work randomx-v2 (re-keyed every 2048 blocks, 64-block lag)
Memória#
Verificar precisa de cerca de 256 MiB por época de chave mantida, e a tabela mantém duas para que uma reorganização atravessando uma fronteira de chave não reconstrua uma por bloco. Orçe mais do que essa tabela, porque a tabela não é o limite. Um cache fica residente a partir do momento em que é alocado e o preenchimento Argon2 que o torna caro vem depois — então até mais dois ficam vivos enquanto estão sendo construídos — e uma entrada despejada enquanto algo ainda a usa retém tudo o que tem até que esse usuário a solte, que é o que um minerador faz ao longo de um preenchimento de dataset.
| Papel | Orçamento | Por quê |
|---|---|---|
| Nó verificador | ~1 GiB para a engine | O pico de cache contra a tabela de duas entradas foi medido em 1280 MiB com os dois efeitos ao mesmo tempo — não os 512 MiB que a tabela sugere. |
| Nó minerador | ~3,3 GiB | Aloca adicionalmente o dataset de ~2 GiB, e é o caso que prende um tomador durante o preenchimento. |
Uma máquina que consegue verificar confortavelmente não consegue necessariamente minerar.
Threads#
O --mine-threads tem como padrão uma por núcleo. Ele não muda nada quanto à validade; é
a velocidade com que este nó procura uma solução.
O que acontece em uma troca de chave#
A função de trabalho recebe uma nova chave a cada randomx_key_interval blocos. Um nó minerador
reconstrói o dataset de ~2 GiB então e para de minerar enquanto o faz — algo da ordem de
dez segundos, dependente da máquina; meça o da sua a partir da primeira fronteira no log.
Ele continua verificando o tempo todo, e uma reconstrução não pode travá-lo: um cabeçalho de qualquer
época de chave que não seja a que está sendo minerada é verificado no cache de 256 MiB da própria época, que o
dataset não toca. Os dois computam digests idênticos, então a única diferença que uma reconstrução faz
para a verificação é a velocidade. O cache da próxima época é aquecido ao longo dos últimos
randomx_key_lag blocos da época.
| Rede | randomx_key_interval | Pausa de mineração, aproximadamente |
|---|---|---|
| mainnet | 2048 blocos | uma a cada ~17 horas |
| testnet pública | 512 blocos | uma a cada ~4 horas |
O intervalo mais curto da testnet é deliberado: ensaiar essa fronteira com mais frequência faz parte do que a rede existe para medir. Construir o dataset da próxima época com antecedência é possível — a chave vem da altura, então é conhecida bem antes da fronteira — e deliberadamente não é feito: significaria manter dois deles, 4 GiB, para poupar uma pausa que custa a um minerador alguns segundos por dia.
Parando um nó minerador#
O SIGTERM (ou Ctrl-C) o para, e ele para prontamente: um sinal
alcança todos os laços, não apenas aquele que por acaso estiver esperando no canal.
Uma parada que acontece durante uma troca de chave espera o preenchimento do dataset terminar
— o motor não libera um buffer de ~2 GiB enquanto chamadas de hash ainda o estiverem lendo, o que
é um use-after-free em C que nenhuma ferramenta Go reportaria. É uma parada esperando um evento fixo
em vez de uma disputando com ele: medido ao longo de dez execuções, o instante de saída não se moveu por mais cedo que o
sinal chegasse, enquanto a espera encolheu de 4,5 s para 0,7 s, sem nenhum SIGSEGV.
Então orçe um tempo limite de parada acima do tempo de preenchimento da sua máquina. Um segundo SIGTERM
não espera — o primeiro devolve o sinal ao sistema operacional, então
pressionar Ctrl-C de novo durante essa pausa mata o processo imediatamente.
Pools, e por que não há nenhuma#
O projeto não opera nenhuma e não endossa nenhuma. O nó minera sozinho por padrão, e com
--stratum-listen ele serve o dialeto Stratum que o XMRig padrão fala, de modo que um software de mineração
externo pode trabalhar contra o seu próprio nó. Esse socket não tem autenticação — qualquer um que
consiga alcançá-lo pode minerar para o próprio pagamento através do seu nó — então vincule-o ao loopback ou a uma rede
em que você confie. Se pools aparecerem, elas são terceiros; aplique o ceticismo que você aplicaria em qualquer lugar.
Botnets, nomeadas em vez de negadas#
A mineração por CPU as convida. Toda moeda minerável por CPU já as combateu e este projeto não espera ser a exceção. A troca é feita de olhos abertos: uma distribuição enviesada por botnets ainda é mais ampla do que uma decidida em uma venda, e manter competitivo o notebook que você já tem é toda a razão de o RandomX existir.
Vendo funcionar#
O explorador da testnet renderiza cada bloco e cada certificado,
inclusive a página que o explorador de nenhuma outra cadeia consegue renderizar: se cada certificado foi aplicado, ou
sofreu omissão e foi cobrado, e qual leitura declarada deixou de valer. Seu próprio nó responde às mesmas
perguntas em /status, /head e /metrics — veja
a superfície somente leitura.