Firme legate alla catena
Una firma ZooBC è valida su una sola catena. Prima di firmare una transazione, un wallet calcola un digest che include l'hash genesi della catena, quindi un pagamento firmato su testnet non risulta valido su mainnet o devnet, anche se la stessa chiave dà lo stesso indirizzo su ogni catena. Lo stesso legame protegge le connessioni tra i nodi e i messaggi firmati fuori dalla catena.
Il digest
Chi firma non firma mai i byte grezzi della transazione. Firma questo digest:
digest = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)
transaction hash = SHA3-256(unsigned transaction bytes ‖ signature)
transaction id = the first 8 bytes of the transaction hash, little-endian
Il tag «ZBC-TX» contrassegna il digest come quello di una transazione; altre azioni firmate usano altri tag (vedi sotto). L'hash genesi lega la firma a una sola catena. Viene accettato solo questo digest legato alla catena: una firma sui byte nudi, senza alcun legame con la catena, viene rifiutata su ogni catena. Vedi firmare una transazione per la procedura di firma completa.
L'hash genesi è l'identità della catena
L'hash genesi è l'hash del primissimo blocco di una catena. Deriva dalla configurazione genesi della catena, quindi cambiare qualsiasi valore incluso in quella configurazione dà un nuovo hash, cioè una catena diversa (vedi blocco genesi). In ZooBC non esiste da nessuna parte un byte separato di identificativo della rete: l'hash genesi è l'unica identità della catena. Devnet, testnet e mainnet hanno ciascuna il proprio (vedi devnet, testnet e mainnet), e una rete di prova rilanciata ne riceve uno nuovo.
Un nodo riporta il genesis_hash e la signing_version della sua catena sulla sua route di informazioni, /api/v1/node/info (vedi API del nodo), così un wallet o uno strumento può sapere per quale catena sta firmando.
Replay tra catene
Supponiamo che un pagamento venga firmato su testnet e che qualcuno lo copi su mainnet. Il nodo di mainnet calcola il digest con l'hash genesi di mainnet, ottiene un valore diverso e la firma non risulta valida: la transazione viene rifiutata come «non firmata per questa catena». L'importo non ha alcun ruolo, e il wallet non deve aggiungere nulla.
La stessa chiave dà lo stesso indirizzo su ogni catena ZooBC, e un indirizzo con fondi su una catena mostra semplicemente un saldo pari a zero su un'altra. È proprio per questo che il legame conta: senza di esso, un pagamento fatto su una catena potrebbe essere copiato su un'altra e spostare monete lì.
Ogni tipo di account, ogni firmatario
Gli account ZooBC possono essere controllati da molti tipi di chiavi: le chiavi Ed25519 proprie di ZooBC, chiavi Bitcoin ed Ethereum e altre (vedi chiavi e tipi di account). Ogni tipo di account firma lo stesso digest legato alla catena; alcuni ne calcolano prima un altro hash, come richiede lo schema di firma della loro catena d'origine (le chiavi in stile Ethereum firmano il suo hash Keccak-256, per esempio). I partecipanti di un account multifirma firmano il digest legato alla catena della transazione interna.
Altre azioni firmate usano digest propri, anch'essi legati alla catena: i consensi che collegano o controllano i gruppi di account («ZBC-GROUP-LINK», «ZBC-GROUP-CONTROL»), la co-firma di un escrow a più parti e la richiesta che annulla una transazione in sospeso nel pool di un nodo («ZBC-CANCEL»).
Nodi e messaggi
Il legame con la catena non si ferma alle transazioni:
- L'handshake tra peer. Quando due nodi si connettono, l'handshake è firmato dalla chiave del nodo e contiene l'hash genesi. Un peer di un'altra catena viene rifiutato con «Genesis hash mismatch», quindi un nodo di una catena non diventa mai peer di un nodo di un'altra.
- Messaggi firmati. I messaggi firmati fuori dalla catena con gli strumenti usano il digest SHA3-256("ZBC-MSG-v2" ‖ hash genesi ‖ messaggio), quindi un messaggio firmato su devnet non risulta mai valido su testnet o mainnet (vedi messaggi firmati e cifrati).
All'interno del protocollo le ricevute fanno eccezione: una ricevuta non nomina alcuna catena, quindi non ha un proprio legame con la catena. Indica però un blocco di riferimento per altezza e hash, che i validatori verificano.