Interaktion mit HyperCore
Lese-Precompiles
Die Testnet-EVM stellt Lese-Precompiles bereit, mit denen HyperCore-Informationen abgefragt werden können. Die Precompile-Adressen beginnen bei 0x0000000000000000000000000000000000000800 und bieten Methoden zum Abfragen von Informationen wie Perp-Positionen, Spot-Guthaben, Vault-Eigenkapital, Staking-Delegierungen, Oracle-Preisen und der L1-Blocknummer.
Die Werte entsprechen garantiert dem aktuellen HyperCore-Zustand zum Zeitpunkt der Erstellung des EVM-Blocks.
Beigefügt ist eine Solidity-Datei L1Read.sol, die die Lese-Precompiles beschreibt. Als Beispiel fragt dieser Aufruf den dritten Perp-Oracle-Preis im Testnet ab:
cast call 0x0000000000000000000000000000000000000807 0x0000000000000000000000000000000000000000000000000000000000000003 --rpc-url https://rpc.hyperliquid-testnet.xyz/evm
Zur Umrechnung in Gleitkommazahlen teilen Sie den zurückgegebenen Preis bei Perps durch 10^(6 - szDecimals) und bei Spot durch 10^(8 - base asset szDecimals).
Precompiles, die mit ungültigen Eingaben wie ungültigen Assets oder einer ungültigen Vault-Adresse aufgerufen werden, geben einen Fehler zurück und verbrauchen das gesamte Gas, das an den Precompile-Aufruf übergeben wurde. Precompiles verursachen Gas-Kosten von 2000 + 65 * (input_len + output_len).
CoreWriter-Contract
Unter 0x3333333333333333333333333333333333333333 steht ein System-Contract zum Senden von Transaktionen von der HyperEVM an HyperCore zur Verfügung. Er verbrennt \~25,000 Gas, bevor er ein Log ausgibt, das von HyperCore als Action verarbeitet wird. Praktisch liegt der Gas-Verbrauch für einen einfachen Aufruf bei \~47000. Eine Solidity-Datei CoreWriter.sol für den Write-System-Contract ist beigefügt.
Details der Action-Kodierung
- Byte 1: Encoding-Version
- Derzeit wird nur Version
1unterstützt, dies ermöglicht jedoch künftige Upgrades bei gleichzeitiger Wahrung der Abwärtskompatibilität. - Bytes 2-4: Action ID
- Diese drei Bytes stellen, als Big-Endian-Ganzzahl ohne Vorzeichen dekodiert, die eindeutige Kennung der Action dar.
- Verbleibende Bytes: Action-Kodierung
- Die übrigen Bytes bilden die actionsspezifischen Daten. Es handelt sich stets um die rohe ABI-Kodierung einer Folge von Solidity-Typen
Um mögliche Latenzvorteile durch die Nutzung der HyperEVM zur Umgehung des L1-Mempools zu verhindern, werden Order-Actions und Vault-Übertragungen, die von CoreWriter gesendet werden, für einige Sekunden on-chain verzögert. Dies hat keine spürbaren Auswirkungen auf die Nutzererfahrung, da der Endnutzer ohnehin mindestens eine Bestätigung durch einen kleinen Block abwarten muss. Diese on-chain verzögerten Actions erscheinen zweimal im L1-Explorer: zuerst als Einreihung und danach als HyperCore-Ausführung.
| Action ID | Action | Fields | Solidity Type | Notes |
|---|---|---|---|---|
| 1 | Limit order | (asset, isBuy, limitPx, sz, reduceOnly, encodedTif, cloid) | (uint32, bool, uint64, uint64, bool, uint8, uint128) | Tif-Kodierung: 1 für Alo , 2 für Gtc , 3 für Ioc . Cloid-Kodierung: 0 bedeutet kein Cloid, andernfalls wird die Zahl als Cloid verwendet. limitPx und sz sollten als 10^8 * des für Menschen lesbaren Werts gesendet werden |
| 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 für Create, 2 für FirstStorageSlot , 3 für CustomStorageSlot . Wenn die Variante Create gewählt wird, wird das Eingabeargument createNonce verwendet. |
| 9 | Add API wallet | (API wallet address, API wallet name) | (address, string) | Wenn der API-Wallet-Name leer ist, wird dies zur primären API-Wallet / zum Agenten |
| 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 wird in Decibps angegeben. Um eine Builder-Gebühr von 0.01% zu genehmigen, sollte maxFreeRate 10 betragen. |
| 13 | Send asset | (destination, subAccount, source_dex, destination_dex, token, wei) | (address, address, uint32, uint32, uint64, uint64) | Wenn subAccount nicht die Nulladresse ist, erfolgt die Übertragung von subAccount. Geben Sie uint32::MAX für source_dex oder destination_dex für Spot an. |
| 15 | Borrow lend operation | (encodedOperation, token, wei) | (uint8, uint64, uint64) | encodedOperation 0 für Supply, 1 für Withdraw . Wenn wei 0 ist, wird die Operation maximal angewendet, z. B. Abheben des gesamten Guthabens aus der Reserve. |
| 16 | Set abstraction | (user, abstraction) | (address, uint8) | abstraction 1 für disabled, 2 für unifiedAccount , 3 für portfolioMargin . user kann entweder der Hauptnutzer oder ein Subkonto sein. |
| 17 | Outcome operation | (encodedOperation, question, outcome, wei) | (uint8, uint32, uint32, uint64) | encodedOperation |
Nachfolgend finden Sie einen Beispiel-Contract, der eine Action im Namen seiner eigenen Contract-Adresse auf HyperCore sendet und zugleich eine Möglichkeit zeigt, die kodierte Action in Solidity zu erstellen.
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);
}
}
\ Viel Erfolg beim Entwickeln. Wir freuen uns über Feedback.
{% file src="/files/4dRObNCsfvnrcSVeJXgc" %}
{% file src="/files/Nsv6L7FugL44GNDvyDq2" %}