Help us shape the future of Go! Take the 2026 Go Developer Survey

staker

command
v0.0.0-...-2cf1f18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: BSD-3-Clause Imports: 22 Imported by: 0

Documentation

Overview

Command staker derives a network's validator staking identities from the mnemonic, so a validator set can be rebuilt from one seed instead of recovered from eight scattered key files.

staker --network 36963 --count 5              the identities, as JSON
staker --network 36963 --count 5 --stakers    the genesis initialStakers array
staker --network 36963 --count 5 --out DIR    staker-i.crt/.key, signer-i.key

WHY THIS EXISTS. Staking identities used to be minted with crypto/rand, one invocation per validator, and kept only as key files. That makes the set unrecoverable the moment the files are: a genesis names NodeIDs, and a NodeID with no private key behind it is a validator nobody can run. Hanzo mainnet was exactly that — five names in a genesis whose keys were on a cluster that is gone, and no seed to rebuild them from.

Derived from the mnemonic, the set is a function of the seed and the network, so it can be recomputed on any machine that can read the seed and nothing has to survive except the seed.

THE DERIVATION. HKDF-SHA256 over the BIP-39 seed, domain-separated by network and role:

material(role, net, i) = HKDF(seed, salt "lux/staking/v1", info "<net>/<role>/<i>")

The network is part of the info string because a primary networkID equals its EVM chainID and is unique per L1 per environment; that is what keeps one seed's Hanzo validators disjoint from its Zoo validators. The role separates the TLS identity from the BLS one, so neither can ever be the other. Nothing here shares material with the account path m/44'/9000'/0'/0/<i> that funds the genesis alloc, so a validator key is never also a funded account.

WHICH NodeID IS REBUILDABLE, AND WHICH IS NOT. A post-quantum profile derives the NodeID from the ML-DSA public key, and FIPS 204 key generation consumes a fixed seed, so that NodeID is a function of the mnemonic and nothing else.

A classical profile derives it from the TLS CERTIFICATE, and that is not reproducible from a seed. staking.NewCertAndKeyBytesFromKey pins the serial and the validity window and seeds its randomness from the key, but Go signs ECDSA with a hedged nonce and randutil.MaybeReadByte reads a byte from the entropy source only some of the time — deliberately, to stop anyone depending on the bytes. Measured: same key, same template, different signature, different DER, different NodeID on every run.

So a classical validator set cannot be rebuilt from the mnemonic. Its keys can be, but its NAMES cannot, and a genesis names NodeIDs. The classical value is reported here for the profile that still uses it; the mnemonic is a complete backup only on the PQ path.

The BLS key goes through localsigner.FromSeed, the node's own seed-to-key derivation.

This tool rolls no crypto. The scalar reduction is the only arithmetic here, and it is the standard wide-reduction: 48 bytes into a 256-bit field leaves a bias below 2^-128.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL