Node numbering
Node ids come from the chain, are sequential from 1, and are never reused. Everything else about numbering is presentation.
How an id is assigned
id = ++totalNodes;
_node[id] =
Node({owner: to, createdAt: uint64(block.timestamp), balance: 0, totalReceived: 0, totalWithdrawn: 0});
_owned[to].push(id);The counter increments first, so the first node ever minted is id 1, not 0. Zero is the empty value: nodeInfo(0) answers with the zero address, and a withdrawal naming an id nobody owns reverts with NotNodeOwner.
Because ids come from a counter inside the transaction, the id is decided by the chain and is final the moment the transaction confirms. Two buyers whose nodes are minted in the same block get different ids, in the order the block orders them. There is no reservation, no queue, and no way to pick your number. You do not send the minting transaction yourself; the relayer sends it after your payment is seen, so the id is assigned then rather than when you paid. See Deploying a node.
Reading #0001
Interfaces display ids zero padded to four digits with a leading hash, so node 1 reads as #0001 and node 137 as #0137. The padding is cosmetic: it keeps columns of ids aligned in a table, which matters when a wallet holds several.
| On chain | Displayed | In the API |
|---|---|---|
1 | #0001 | 1 |
42 | #0042 | 42 |
13705 | #13705 | 13705 |
Ids longer than four digits are not truncated; the padding simply stops applying. When you call the contract or the API, pass the plain number without the hash and without leading zeros.
totalNodes is also the count
Since ids are sequential and never reused, totalNodes() is both the highest id issued and the number of nodes that have ever existed. There is no burn, so nothing lowers it.
cast call $FACTORY "totalNodes()(uint256)"
cast call $FACTORY "nodeInfo(uint256)(address,uint64,uint256,uint256,uint256)" 1The same figure is served as totalNodes by GET /api/stats.
Two ids, and when they differ
The operator’s database has its own row identifier for each node, separate from the chain id. They usually match, and they are not required to: the database row is created when the mint is indexed, while the chain id was assigned when the transaction ran.
The API is explicit about which is which. chainNodeId is the number the contract knows, and it is the one to pass to withdraw or nodeInfo. When in doubt, trust the chain id, because it is the only one your money responds to.
#0001 and the number the contract accepts.What an id does not tell you
- It does not confer priority. A low id is not paid first, more, or sooner than a high one.
- It does not indicate value. Rounds credit active nodes; the id plays no part in the amount.
- It is not scarce in any enforced way. There is no fixed supply of nodes, and no cap on
totalNodes.
If any of those properties would change your decision to deploy, read Risks before you spend anything.