Hyperliquid的预编译合约(precompiles)

🧩 一、什么是预编译合约(Precompiled Contract)

预编译合约(Precompile) 是一种在特定地址上内置于 EVM(Ethereum Virtual Machine)中的系统合约。
它不像普通智能合约那样用 Solidity 编写、部署在区块链上,而是直接用底层语言(C++/Rust/Go)实现并编译进客户端

简言之:

它看起来像智能合约(有地址、有调用接口),
但实际上执行的是客户端原生代码。


⚙️ 二、为什么需要 Precompile?

普通 Solidity 智能合约运行在 EVM 字节码层,
这意味着每一个数学操作、哈希、签名验证都要通过 opcode 执行,成本高、性能低。

而某些操作(例如椭圆曲线签名验证、哈希函数计算、跨模块访问系统状态等):

  • 用纯 Solidity 实现会非常昂贵;
  • 但又是区块链协议必须的功能。

于是以太坊在设计时,引入了 预编译合约机制

✅ 让系统在固定地址上,提供高性能、低 gas 成本的“内置函数”。
✅ 用户可以像调用合约一样访问它们。
✅ 保持“智能合约接口兼容性”,不破坏 EVM 设计。


🧱 三、以太坊上的经典 Precompile 合约

地址 功能 示例用途
0x01 ecrecover 从签名恢复公钥地址
0x02 sha256 计算 SHA-256 哈希
0x03 ripemd160 计算 RIPEMD-160 哈希
0x04 identity 返回输入数据本身
0x050x08 modexp, bn256Add, bn256Mul, bn256Pairing 椭圆曲线操作,用于 zk、BLS 验证
0x090x0A(某些链扩展) blake2f, keccak256 额外哈希与密码学运算

这些地址上的合约由客户端(如 Geth、Erigon、Nethermind)实现,而不是在链上部署。


💡 四、在以太坊兼容链中的扩展(如 Hyperliquid)

许多 自研 L2、EVM 兼容链 会添加自己的预编译合约,用于:

功能类别 示例 作用
系统信息访问 0x4200... 获取当前链 ID、区块号、时间戳 快速访问系统状态
跨模块调用 Hyperliquid 的 MARK_PRICE_PRECOMPILE 允许合约直接访问核心撮合引擎数据(如标记价格、账户保证金)
跨链通信 Arbitrum、zkSync 的 bridge precompile 合约层可直接发跨链消息
性能优化 Curve、zk 系列链的数学 precompile 快速执行复杂计算(pairing、FFT 等)

🧠 五、工作机制(技术细节)

当合约调用一个预编译合约地址时(例如 0x01),EVM 内部执行流程是:

1️⃣ 检测地址范围
如果调用目标在 0x01–0xFF 或链定义的 precompile 地址区间内 → 进入预编译逻辑。

2️⃣ 交由客户端实现执行
EVM 不解释字节码,而直接跳转到客户端的内置函数(例如 Geth 的 Go 函数)。

3️⃣ 返回结果到 EVM 栈
执行完后将结果数据(如哈希、签名恢复结果、价格数据等)返回给调用者。

示例(伪代码):

(bool success, bytes memory result) = address(0x01).staticcall(data);

→ 实际上调用的是 Go 实现的 ecrecover() 函数。


🔍 六、Hyperliquid 中的预编译合约用途

Hyperliquid 的核心撮合和保证金系统运行在链下的 HyperCore Engine 中,
而链上合约运行在 HyperEVM 环境中。

为了让链上逻辑能访问链下状态(如标记价格、仓位、清算数据),
Hyperliquid 定义了一组 系统预编译合约(System Precompiles)

功能 地址(示例) 返回值
获取标记价格 0x000...MARKPRICE 当前合约市场的 Mark Price
查询账户保证金 0x000...MARGIN 用户保证金余额与杠杆率
查询资金费率 0x000...FUNDING 当前 funding 状态
触发清算(内部调用) 0x000...LIQUIDATE 强平逻辑入口

这些接口:

  • 无需依赖外部 oracle;
  • 可在任意智能合约中调用;
  • 保证执行结果与撮合引擎的状态一致;
  • 通常以 staticcall() 的形式访问。

⚡️ 七、调用示例(Solidity)

pragma solidity ^0.8.20;

contract PriceReader {
    address constant MARK_PRICE_PRECOMPILE = 0x0000000000000000000000000000000000000801;

    function getMarkPrice(uint32 marketId) public view returns (uint64) {
        (bool ok, bytes memory data) = MARK_PRICE_PRECOMPILE.staticcall(abi.encode(marketId));
        require(ok, "precompile failed");
        return abi.decode(data, (uint64));
    }
}

这个调用会:

  • 直接从 HyperCore 的共享内存中读取最新 mark price;
  • 返回给合约,不需上链事件或 oracle。

🧭 八、设计优点

优点 说明
🚀 性能极高 由原生代码执行,比字节码快几个数量级
🛡 安全性高 逻辑由协议层控制,不可被用户篡改
💬 接口兼容性好 用合约调用方式暴露系统函数
🔗 无中心化依赖 所有节点执行相同预编译逻辑,保持共识一致

⚠️ 九、设计注意点

限制 含义
地址固定 必须提前定义,部署后不可更改
升级需硬分叉 因为逻辑编译在客户端,更新需链级升级
不支持复杂状态存储 通常为“纯函数”,不能直接修改链上状态

✅ 十、一句话总结

预编译合约(Precompiles) 就是“系统级内置函数”:
用原生代码实现,暴露为固定合约地址,
既像智能合约那样可调用,又具备内核级性能。

在 Hyperliquid 中,预编译合约让链上逻辑能直接访问核心撮合引擎数据(如标记价、保证金),
从而实现高性能 + 去中心化的一体化交易系统。


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容