Firmare una transazione
Una firma dimostra che chi detiene la chiave di un account ha approvato una transazione, byte per byte. Su ZooBC chi firma non firma mai la transazione nuda: firma un digest che copre anche l'identità della catena, quindi la firma è valida su una sola catena. Possono firmare account di molti tipi di chiave, ciascuno con lo schema della propria catena d'origine, il che permette a una chiave Bitcoin, Ethereum o Solana di controllare direttamente un account ZooBC.
Che cosa viene firmato
Chi firma prende l'involucro non firmato, cioè ogni campo tranne la firma, e firma questo digest:
digest = SHA3-256( "ZBC-TX" ‖ genesis block hash ‖ unsigned bytes )
«ZBC-TX» è un tag ASCII, e ‖ significa «seguito da». Viene accettato solo questo digest legato alla catena. In una transazione di versione 3 i 4 byte di scadenza fanno parte dei byte non firmati, quindi vengono firmati come ogni altro campo.
L'hash del blocco genesi è l'identità della catena. ZooBC non ha un campo di identificativo della rete: devnet, testnet e mainnet hanno ciascuna il proprio hash genesi, quindi una firma fatta per mainnet non è valida su devnet o testnet, anche quando la stessa chiave detiene fondi su tutte e tre. I nodi confrontano inoltre gli hash genesi prima di connettersi tra loro. Questo chiude la porta al replay tra catene, in cui qualcuno copia la tua transazione da una catena all'altra; vedi firme legate alla catena.
L'hash e l'id
Una volta firmata, una transazione è identificata dal suo hash e dal suo id:
hash = SHA3-256( unsigned bytes ‖ signature )
id = the first 8 bytes of the hash, read as a little-endian signed 64-bit integer
Un nodo rifiuta un id già confermato, il che impedisce un replay sulla stessa catena. L'id di una transazione IssueToken è anche l'id del token che crea (vedi emettere un token).
Tipi di chiave che possono firmare
Un indirizzo inizia con un numero di tipo, e il tipo decide come viene verificata la sua firma:
| Tipo di chiave (numero) | Schema di firma |
|---|---|
| ZooBC (0), Solana (11) | Ed25519 |
| Cardano (13), Tezos (16) | Ed25519, con la chiave pubblica trasportata in un campo firma di 98 byte |
| Bitcoin legacy (1), P2PKH (5), P2WPKH annidato in P2SH (6), P2WPKH (7), Ripple (14) | ECDSA secp256k1 su un doppio SHA-256 del digest, con la chiave pubblica trasportata |
| Ethereum (4), Tron (15) | secp256k1 su Keccak-256 del digest; la chiave viene recuperata da una firma r‖s‖v di 65 byte |
| Bitcoin Taproot (9) | Schnorr BIP-340 |
| Polkadot (12) | sr25519 |
Le firme ECDSA devono usare la forma low-s. Qualunque sia lo schema, ogni chiave firma lo stesso digest legato alla catena.
Alcuni tipi di indirizzo non possono mai firmare: Empty (2), Estonia eID (3, che non ha un verificatore), gli script Bitcoin P2WSH (8) e i dataset (10). Un indirizzo P2WSH rappresenta uno script anziché una singola chiave, e un indirizzo di dataset indica dati, non un firmatario. Gli account senza chiave, come i pool di sistema, i gruppi di account e gli account multifirma, non hanno alcuna chiave e spendono solo secondo le proprie regole.
Firmare con un wallet esterno
Un wallet esterno può anche firmare una transazione della propria catena e farla trasportare, come messaggio, all'interno della transazione ZooBC corrispondente:
- Ethereum: una transazione legacy, EIP-2930 o EIP-1559 con una access list vuota;
- Solana: un trasferimento System;
- Bitcoin: un input, uno o due output e una commissione pari a zero.
Il nodo verifica che mittente, destinatario e importo corrispondano alla transazione ZooBC, e un dato payload esterno può essere speso una sola volta. Un messaggio del genere può contenere fino a 4.096 byte. Vedi MetaMask e accesso in stile Ethereum per l'accesso in stile Ethereum.
Altri digest firmati
Lo stesso schema legato alla catena, ogni volta con il proprio tag, copre altri consensi:
- collegare un indirizzo a un gruppo e cedere il controllo di un gruppo («ZBC-GROUP-LINK» e «ZBC-GROUP-CONTROL»);
- chiedere a un nodo di annullare una transazione in sospeso nel suo pool («ZBC-CANCEL»);
- la co-firma di un escrow a più parti.
I messaggi off-chain, che non sono transazioni, vengono firmati come SHA3-256("ZBC-MSG-v2" ‖ genesis hash ‖ message) con una chiave Ed25519; vedi messaggi firmati e cifrati.