HyperCore との相互作用
Read プリコンパイル
テストネットの EVM は、HyperCore の情報を照会できる Read プリコンパイルを提供します。プリコンパイルアドレスは 0x0000000000000000000000000000000000000800 から始まり、永続契約ポジション、スポット残高、ボールトエクイティ、ステーキングデリゲーション、オラクル価格、L1 ブロック番号などの情報を照会するメソッドを持ちます。
これらの値は、EVM ブロックが構築された時点の最新の HyperCore 状態と一致することが保証されます。
Read プリコンパイルを記述した Solidity ファイル L1Read.sol が添付されています。例として、この呼び出しはテストネットの 3 番目の永続契約オラクル価格を照会します:
cast call 0x0000000000000000000000000000000000000807 0x0000000000000000000000000000000000000000000000000000000000000003 --rpc-url https://rpc.hyperliquid-testnet.xyz/evm
浮動小数点数に変換するには、永続契約の場合は返された価格を 10^(6 - szDecimals) で、スポットの場合は 10^(8 - base asset szDecimals) で割ります。
無効な資産やボールトアドレスなどの無効な入力でプリコンパイルを呼び出すと、エラーを返し、プリコンパイル呼び出しフレームに渡されたガスをすべて消費します。プリコンパイルのガスコストは 2000 + 65 * (input_len + output_len) です。
CoreWriter コントラクト
HyperEVM から HyperCore へトランザクションを送信するためのシステムコントラクトが 0x3333333333333333333333333333333333333333 にあります。HyperCore がアクションとして処理するログを発行する前に \~25,000 ガスを消費します。実際には、基本的な呼び出しのガス使用量は \~47000 になります。書き込み用システムコントラクトの Solidity ファイル CoreWriter.sol が添付されています。
アクションエンコーディングの詳細
- バイト 1: エンコーディングバージョン
- 現在はバージョン
1のみがサポートされていますが、後方互換性を維持したまま将来のアップグレードを可能にします。 - バイト 2〜4: アクション ID
- これら 3 バイトは、ビッグエンディアンの符号なし整数としてデコードされた場合、アクションの一意の識別子を表します。
- 残りのバイト: アクションエンコーディング
- 残りのバイトはアクション固有のデータを構成します。常に Solidity 型の列の生の ABI エンコーディングです
HyperEVM を使って L1 のメモリプールをバイパスすることによる潜在的なレイテンシ上の優位性を防ぐため、CoreWriter から送信された注文アクションとボールト送金は、オンチェーンで数秒遅延されます。エンドユーザーは少なくとも 1 つのスモールブロックの確認を待つ必要があるため、これは UX に顕著な影響を与えません。これらのオンチェーンで遅延されたアクションは、L1 エクスプローラーに 2 回表示されます: 最初にエンキューとして、次に 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) | Tif encoding: 1 for Alo , 2 for Gtc , 3 for Ioc . Cloid encoding: 0 means no cloid, otherwise uses the number as the cloid. limitPx and sz should be sent as 10^8 * the human readable value |
| 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 for Create, 2 for FirstStorageSlot , 3 for CustomStorageSlot . If Create variant, then createNonce input argument is used. |
| 9 | Add API wallet | (API wallet address, API wallet name) | (address, string) | If the API wallet name is empty then this becomes the main API wallet / 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 is in decibps. To approve a builder fee of 0.01% maxFreeRate should be 10. |
| 13 | Send asset | (destination, subAccount, source_dex, destination_dex, token, wei) | (address, address, uint32, uint32, uint64, uint64) | If subAccount is not the zero address, then transfer from subAccount. Specify uint32::MAX for the source_dex or destination_dex for spot. |
| 15 | Borrow lend operation | (encodedOperation, token, wei) | (uint8, uint64, uint64) | encodedOperation 0 for Supply, 1 for Withdraw . If wei is 0 then maximally apply the operation, e.g. withdraw full balance from reserve. |
| 16 | Set abstraction | (user, abstraction) | (address, uint8) | abstraction 1 for disabled, 2 for unifiedAccount , 3 for portfolioMargin . user can either be the master user or a sub-account. |
| 17 | Outcome operation | (encodedOperation, question, outcome, wei) | (uint8, uint32, uint32, uint64) | encodedOperation |
以下は、HyperCore 上で自身のコントラクトアドレスの代理としてアクションを送信するコントラクトの例であり、Solidity でエンコードされたアクションを構築する 1 つの方法を示しています。
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);
}
}
\ 楽しい開発を。フィードバックは歓迎します。
{% file src="/files/4dRObNCsfvnrcSVeJXgc" %}
{% file src="/files/Nsv6L7FugL44GNDvyDq2" %}