Interazione con HyperCore
Precompiles di lettura
L'EVM su testnet fornisce precompiles di lettura che consentono di interrogare le informazioni di HyperCore. Gli indirizzi dei precompiles iniziano da 0x0000000000000000000000000000000000000800 e dispongono di metodi per interrogare informazioni quali posizioni perpetual, saldi spot, capitale proprio del vault, deleghe di staking, prezzi oracle e il numero del blocco L1.
I valori sono garantiti corrispondere allo stato più recente di HyperCore al momento della costruzione del blocco EVM.
È allegato un file Solidity L1Read.sol che descrive i precompiles di lettura. Come esempio, questa chiamata interroga il terzo prezzo oracle dei perpetual su testnet:
cast call 0x0000000000000000000000000000000000000807 0x0000000000000000000000000000000000000000000000000000000000000003 --rpc-url https://rpc.hyperliquid-testnet.xyz/evm
Per convertire in numeri in virgola mobile, dividere il prezzo restituito per 10^(6 - szDecimals) per i perpetual e per 10^(8 - base asset szDecimals) per spot.
I precompiles invocati con input non validi, come asset o indirizzi vault non validi, restituiscono un errore e consumano tutto il gas passato al frame di chiamata del precompile. I precompiles hanno un costo in gas pari a 2000 + 65 * (input_len + output_len).
Contratto CoreWriter
È disponibile un contratto di sistema all'indirizzo 0x3333333333333333333333333333333333333333 per inviare transazioni dall'HyperEVM a HyperCore. Esso brucia \~25,000 gas prima di emettere un log che viene elaborato da HyperCore come action. In pratica, il consumo di gas per una chiamata di base è di \~47000. È allegato un file Solidity CoreWriter.sol per il contratto di sistema di scrittura.
Dettagli della codifica delle action
- Byte 1: versione della codifica
- Attualmente è supportata solo la versione
1, ma ciò consente futuri aggiornamenti mantenendo la compatibilità con le versioni precedenti. - Byte 2-4: Action ID
- Questi tre byte, decodificati come numero intero senza segno in formato big-endian, rappresentano l'identificatore univoco dell'action.
- Byte rimanenti: codifica dell'action
- I byte rimanenti costituiscono i dati specifici dell'action. È sempre la codifica ABI grezza di una sequenza di tipi Solidity
Per evitare qualsiasi potenziale vantaggio in termini di latenza derivante dall'uso dell'HyperEVM per aggirare il mempool L1, le action sugli ordini e i trasferimenti del vault inviati da CoreWriter vengono ritardati on-chain per alcuni secondi. Ciò non ha effetti percepibili sull'esperienza utente, poiché l'utente finale deve comunque attendere almeno una conferma di un blocco piccolo. Queste action ritardate on-chain compaiono due volte nell'explorer L1: prima come accodamento e poi come esecuzione su HyperCore.
| Action ID | Action | Fields | Solidity Type | Notes |
|---|---|---|---|---|
| 1 | Limit order | (asset, isBuy, limitPx, sz, reduceOnly, encodedTif, cloid) | (uint32, bool, uint64, uint64, bool, uint8, uint128) | Codifica Tif: 1 per Alo , 2 per Gtc , 3 per Ioc . Codifica Cloid: 0 indica nessun cloid, altrimenti utilizza il numero come cloid. limitPx e sz devono essere inviati come 10^8 * il valore leggibile in formato umano |
| 2 | Vault transfer | (vault, isDeposit, usd) | (address, bool, uint64) | |
| 3 | Token delegate | (validator, wei, isUndelegate) | (address, uint64, bool) | |
| 4 | Staking deposit | wei | uint64 | |
| 5 | Staking withdraw | wei | uint64 | |
| 6 | Spot send | (destination, token, wei) | (address, uint64, uint64) | |
| 7 | USD class transfer | (ntl, toPerp) | (uint64, bool) | |
| 8 | Finalize EVM Contract | (token, encodedFinalizeEvmContractVariant, createNonce) | (uint64, uint8, uint64) | encodedFinalizeEvmContractVariant 1 per Create, 2 per FirstStorageSlot , 3 per CustomStorageSlot . Se si utilizza la variante Create, viene impiegato l'argomento di input createNonce. |
| 9 | Add API wallet | (API wallet address, API wallet name) | (address, string) | Se il nome del wallet API è vuoto, questo diventa il wallet API principale / agent |
| 10 | Cancel order by oid | (asset, oid) | (uint32, uint64) | |
| 11 | Cancel order by cloid | (asset, cloid) | (uint32, uint128) | |
| 12 | Approve builder fee | (maxFeeRate, builder address) | (uint64, address) | maxFeeRate è espresso in decibps. Per approvare una commissione builder dello 0.01%, maxFreeRate deve essere 10. |
| 13 | Send asset | (destination, subAccount, source_dex, destination_dex, token, wei) | (address, address, uint32, uint32, uint64, uint64) | Se subAccount non è l'indirizzo zero, il trasferimento avviene da subAccount. Specificare uint32::MAX per source_dex o destination_dex per spot. |
| 15 | Borrow lend operation | (encodedOperation, token, wei) | (uint8, uint64, uint64) | encodedOperation 0 per Supply, 1 per Withdraw . Se wei è 0, l'operazione viene applicata nella misura massima, ad esempio prelevando l'intero saldo dalla riserva. |
| 16 | Set abstraction | (user, abstraction) | (address, uint8) | abstraction 1 per disabled, 2 per unifiedAccount , 3 per portfolioMargin . user può essere l'utente principale oppure un subaccount. |
| 17 | Outcome operation | (encodedOperation, question, outcome, wei) | (uint8, uint32, uint32, uint64) | encodedOperation |
Di seguito è riportato un contratto di esempio che invia un'action per conto del proprio indirizzo del contratto su HyperCore, e che mostra anche un modo per costruire l'action codificata in Solidity.
contract CoreWriterCaller {
function sendUsdClassTransfer(uint64 ntl, bool toPerp) external {
bytes memory encodedAction = abi.encode(ntl, toPerp);
bytes memory data = new bytes(4 + encodedAction.length);
data[0] = 0x01;
data[1] = 0x00;
data[2] = 0x00;
data[3] = 0x07;
for (uint256 i = 0; i < encodedAction.length; i++) {
data[4 + i] = encodedAction[i];
}
CoreWriter(0x3333333333333333333333333333333333333333).sendRawAction(data);
}
}
\ Buon lavoro di sviluppo. Ogni feedback è apprezzato.
{% file src="/files/4dRObNCsfvnrcSVeJXgc" %}
{% file src="/files/Nsv6L7FugL44GNDvyDq2" %}