Nonce e wallet API
Contesto
Una L1 decentralizzata deve prevenire gli attacchi di replay. Quando un utente firma una transazione di trasferimento USDC, il destinatario non può trasmetterla più volte per svuotare il wallet del mittente. Per risolvere questo problema, Ethereum memorizza un "nonce" per ciascun indirizzo, ossia un numero che parte da 0. Ogni transazione deve utilizzare esattamente "nonce + 1" per essere inclusa.
Wallet API
Nella documentazione sono noti anche come agent wallets. Un account master può autorizzare i wallet API a firmare per conto dell'account master o di uno qualsiasi dei subaccount.
Si noti che i wallet API vengono utilizzati esclusivamente per firmare. Per interrogare i dati dell'account associati a un account master o subaccount, è necessario passare l'indirizzo effettivo di tale account. Un errore comune consiste nell'utilizzare l'agent wallet, che produce un risultato vuoto.
Eliminazione dei wallet API
I wallet API e il relativo stato dei nonce possono essere eliminati nei seguenti casi:
- Il wallet viene deregistrato. Questo accade a un wallet API senza nome esistente quando viene inviata un'azione ApproveAgent per registrare un nuovo wallet API senza nome. Accade anche a un wallet API con nome esistente quando viene inviata un'azione ApproveAgent con un nome corrispondente.
- Il wallet scade.
- L'account che ha registrato l'agent non dispone più di fondi.
Importante: per chi utilizza i wallet API a livello programmatico, si sconsiglia vivamente di riutilizzare i relativi indirizzi. Una volta che un agent viene deregistrato, lo stato dei nonce utilizzati può essere eliminato. Generare un nuovo agent wallet per gli utilizzi futuri per evitare comportamenti imprevisti. Ad esempio, azioni firmate in precedenza possono essere riprodotte una volta eliminato l'insieme dei nonce.
Nonce di Hyperliquid
Il design di Ethereum non funziona per un book degli ordini onchain. Una strategia di market making può inviare migliaia di ordini e annullamenti in un secondo. Richiedere un ordinamento preciso di inclusione sulla blockchain comprometterebbe qualsiasi strategia.
Su Hyperliquid, vengono memorizzati i 100 nonce più alti per indirizzo. Ogni nuova transazione deve avere un nonce maggiore del nonce più piccolo in questo insieme e non deve inoltre essere mai stato utilizzato in precedenza. I nonce vengono tracciati per firmatario, che corrisponde all'indirizzo utente se firmato con la chiave privata dell'indirizzo, oppure all'indirizzo dell'agent se firmato con un wallet API.
I nonce devono rientrare in (T - 2 days, T + 1 day), dove T è il timestamp unix in millisecondi del blocco della transazione.
I seguenti passaggi possono essere utili per trasferire una strategia automatizzata da un exchange centralizzato:
- Utilizzare un wallet API per ciascun processo di trading. Si noti che i nonce vengono memorizzati per firmatario (ossia per chiave privata), quindi subaccount distinti firmati dallo stesso wallet API condivideranno il tracciamento dei nonce del wallet API. Si consiglia di utilizzare wallet API distinti per subaccount diversi.
- In ciascun processo di trading, prevedere un'attività che raggruppi periodicamente le richieste di ordini e annullamenti ogni 0.1 secondi. Si consiglia di raggruppare gli ordini IOC e GTC separatamente dagli ordini ALO, poiché i batch contenenti solo ordini ALO vengono prioritizzati dai validatori.
- Le attività di logica di trading inviano ordini e annullamenti all'attività di raggruppamento.
- Per ciascun batch di ordini o annullamenti, recuperare e incrementare un contatore atomico che garantisca un nonce univoco per l'indirizzo. Se necessario, il contatore atomico può essere avanzato ai millisecondi unix correnti.
Questa struttura è robusta rispetto a transazioni fuori sequenza entro 2 secondi, il che dovrebbe essere sufficiente per una strategia automatizzata geograficamente vicina a un server API.
Suggerimenti per gli utenti di subaccount e vault
Si noti che i nonce vengono memorizzati per firmatario, ossia per l'indirizzo della chiave privata utilizzata per firmare la transazione. Pertanto, si consiglia che ciascun processo di trading o sessione frontend utilizzi una chiave privata distinta per la firma. In particolare, un singolo wallet API che firma per un utente, un vault o un subaccount condivide lo stesso insieme di nonce.
Se gli utenti desiderano utilizzare più subaccount in parallelo, è più semplice generare due wallet API distinti sotto l'account master e utilizzare un wallet API per ciascun subaccount. Questo evita collisioni tra gli insiemi di nonce utilizzati da ciascun subaccount.