与 HyperCore 交互
读取预编译合约
测试网 EVM 提供读取预编译合约,允许查询 HyperCore 信息。预编译合约地址从 0x0000000000000000000000000000000000000800 开始,提供查询永续仓位、现货余额、金库权益、质押委托、预言机价格以及 L1 区块号等信息的方法。
这些值保证与构建 EVM 区块时的最新 HyperCore 状态一致。
随附一个描述读取预编译合约的 Solidity 文件 L1Read.sol。例如,以下调用查询测试网上的第三个永续预言机价格:
cast call 0x0000000000000000000000000000000000000807 0x0000000000000000000000000000000000000000000000000000000000000003 --rpc-url https://rpc.hyperliquid-testnet.xyz/evm
要转换为浮点数,永续合约需将返回的价格除以 10^(6 - szDecimals),现货需除以 10^(8 - base asset szDecimals)。
以无效输入(例如无效资产或金库地址)调用预编译合约会返回错误,并消耗传入预编译调用帧的全部 Gas。预编译合约的 Gas 成本为 2000 + 65 * (input_len + output_len)。
CoreWriter 合约
在 0x3333333333333333333333333333333333333333 处有一个系统合约,用于从 HyperEVM 向 HyperCore 发送交易。它先消耗 \~25,000 Gas,再发出一条由 HyperCore 作为操作处理的日志。实践中,一次基本调用的 Gas 用量约为 \~47000。随附写入系统合约的 Solidity 文件 CoreWriter.sol。
操作编码细节
- 字节 1:编码版本
- 目前仅支持版本
1,但它支持在保持向后兼容的同时进行未来升级。 - 字节 2-4:操作 ID
- 这三个字节按大端序无符号整数解码时,表示该操作的唯一标识符。
- 其余字节:操作编码
- 其余字节构成操作特定的数据,始终是一系列 Solidity 类型的原始 ABI 编码
为防止利用 HyperEVM 绕过 L1 内存池获得任何潜在的延迟优势,从 CoreWriter 发送的订单操作和金库划转会在链上延迟几秒执行。这对用户体验没有明显影响,因为最终用户至少要等待一个小区块确认。这些链上延迟的操作在 L1 浏览器中出现两次:第一次是入队,第二次是 HyperCore 执行。
| 操作 ID | 操作 | 字段 | Solidity 类型 | 说明 |
|---|---|---|---|---|
| 1 | 限价订单 | (asset, isBuy, limitPx, sz, reduceOnly, encodedTif, cloid) | (uint32, bool, uint64, uint64, bool, uint8, uint128) | Tif 编码:1 为 Alo,2 为 Gtc,3 为 Ioc。Cloid 编码:0 表示无 cloid,否则使用该数字作为 cloid。limitPx 和 sz 应按 10^8 * 人类可读值发送 |
| 2 | 金库划转 | (vault, isDeposit, usd) | (address, bool, uint64) | |
| 3 | 代币委托 | (validator, wei, isUndelegate) | (address, uint64, bool) | |
| 4 | 质押充值 | wei | uint64 | |
| 5 | 质押提币 | wei | uint64 | |
| 6 | 现货发送 | (destination, token, wei) | (address, uint64, uint64) | |
| 7 | USD 类划转 | (ntl, toPerp) | (uint64, bool) | |
| 8 | 完成 EVM 合约 | (token, encodedFinalizeEvmContractVariant, createNonce) | (uint64, uint8, uint64) | encodedFinalizeEvmContractVariant:1 为 Create,2 为 FirstStorageSlot,3 为 CustomStorageSlot。若为 Create 变体,则使用 createNonce 输入参数。 |
| 9 | 添加 API 钱包 | (API wallet address, API wallet name) | (address, string) | 如果 API 钱包名称为空,则它成为主 API 钱包 / agent |
| 10 | 按 oid 撤单 | (asset, oid) | (uint32, uint64) | |
| 11 | 按 cloid 撤单 | (asset, cloid) | (uint32, uint128) | |
| 12 | 批准 builder 费用 | (maxFeeRate, builder address) | (uint64, address) | maxFeeRate 以 decibps 为单位。要批准 0.01% 的 builder 费用,maxFreeRate 应为 10。 |
| 13 | 划转资产 | (destination, subAccount, source_dex, destination_dex, token, wei) | (address, address, uint32, uint32, uint64, uint64) | 如果 subAccount 不是零地址,则从 subAccount 划转。现货的 source_dex 或 destination_dex 指定为 uint32::MAX。 |
| 15 | 借贷操作 | (encodedOperation, token, wei) | (uint8, uint64, uint64) | encodedOperation:0 为 Supply,1 为 Withdraw。若 wei 为 0,则最大程度执行该操作,例如从储备中提取全部余额。 |
| 16 | 设置抽象 | (user, abstraction) | (address, uint8) | abstraction:1 为 disabled,2 为 unifiedAccount,3 为 portfolioMargin。user 可以是主用户或子账户。 |
| 17 | 结果操作 | (encodedOperation, question, outcome, wei) | (uint8, uint32, uint32, uint64) | encodedOperation |
下面是一个示例合约,它代表自己的合约地址在 HyperCore 上发送操作,同时演示了在 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);
}
}
\ 祝构建顺利。欢迎任何反馈。
{% file src="/files/4dRObNCsfvnrcSVeJXgc" %}
{% file src="/files/Nsv6L7FugL44GNDvyDq2" %}