> For the complete documentation index, see [llms.txt](https://docs.rome.builders/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rome.builders/zh/can-kao/precompiles.md).

# 预编译合约参考

Rome 的 Solana 互操作预编译合约中的每个方法——地址、Solidity 签名、选择器，以及它是读取、调用还是构造一个 CPI。

Rome 的链上程序按预编译合约分派的选择器。选择器 = `keccak256(signature)[:4]`；下方每一行均据此验证。Solidity 接口位于 [`rome-solidity/contracts/interface.sol`](https://github.com/rome-protocol/rome-solidity/blob/master/contracts/interface.sol).

**请先阅读 Dispatch 列。** 它说明一个方法对 Solana 状态的作用：

| 分派                  | 发生什么                                                                             | 真实 Solana CPI | 允许在迭代执行中使用      |
| ------------------- | -------------------------------------------------------------------------------- | ------------- | --------------- |
| `调用` / `组合式`        | 一个或多个 CPI；在适用种子时，以调用者的外部权限 PDA 身份签名。在 **旧版** 轨道上会立即执行；在 **缓存** 轨道上则暂存，并在交易结束时提交。 | 是             | 旧版： **否**。缓存版：是 |
| `EthCall`           | 纯计算，或读取 Rome 自身状态                                                                | 否             | 是               |
| `CrossStateEthCall` | 读取经模拟预加载的另一 Solana 账户字节。无 CPI，无副作用。                                              | 否             | 是               |
| `预编译`               | 确定性密码学操作（以太坊标准预编译合约）                                                             | 否             | 是               |

一个合约使用 **一条轨道**：要么使用旧版预编译合约（`0xff…07`, `0xff…08`, `0xff…09`, `0x42…16`），要么使用缓存版（`0xff…04`, `0xff…05`, `0xff…06`, `0xff…0b`）。运行时拒绝在同一交易中混用两者的变更调用。读取仍被允许，但有一个例外：一旦已触发缓存轨道调用，交易剩余时间内将拒绝旧版轨道读取。请参见 [集成 Solana 程序](/zh/kai-fa-zhe-zhi-nan/integrate-solana-program.md).

**谁付费。** Solana 手续费付款方预先支付旧版轨道 CPI 花费的每一 lamport（租金、转账、 `swap_gas_to_lamports`）；程序会在每次 CPI 前后衡量付款方余额，并按 gas 价格将净支出作为 gas 向用户计费，同时退还 CPI 返回的 lamport。

**谁签名。** 调用预编译合约的合约以自身身份行事：签名者是该合约的外部权限 PDA（`["EXTERNAL_AUTHORITY", contract]`）。只有当用户直接向预编译地址发送交易时，用户自身的 PDA 才会签名。在 `DELEGATECALL` / `CALLCODE`下，变更选择器会被拒绝，但以下情况除外： `create_ata*`, `create_pda*`, `swap_gas_to_lamports`, `init_spl_mint` 和 `create_and_init_mint` 位于 HelperProgram 上的 `create_ata*` 位于 ASplCached 上的，以及 `invoke` / `invoke_signed` 位于 CpiProgram 上的。它们获得豁免是因为其目标绑定于调用者或由操作员出资，而非因为它们无需签名： `create_and_init_mint` 仍使用外层调用者的 PDA 签名以支付铸币的租金，并且只能创建权限为该 PDA 的铸币，且 `invoke` / `invoke_signed` 拒绝裸权限（`DelegatecallOwnerAuthority`），并按正在运行的合约地址为带盐 PDA 划分命名空间。

每个方法均不可支付（`msg.value > 0` 会以以下错误回退： `TransferProhibited`），但以下除外： `withdrawal(bytes32)`。标记为 *仅单状态* 的方法会在 op-geth-stack 链上被拒绝。CPI 不得指定 Solana 手续费付款方（普通 System 转账指令内除外）或 Rome 程序，且不得调用 Rome 程序。

## SystemCached（`0xff00000000000000000000000000000000000004`)

PDA 创建加系统程序操作（分配、分派、lamport 转账），暂存至覆盖层。是旧版 `System @ 0xff..07`的变更选择器的缓存版对应项（旧版 System 保留纯读取选择器）。

| Solidity 签名                          | 选择器          | 分派   | 说明                                |
| ------------------------------------ | ------------ | ---- | --------------------------------- |
| `create_pda()`                       | `0xe0402a8d` | `调用` | 创建调用者的 `external_auth` PDA，免租，零数据 |
| `create_pda(uint64)`                 | `0x4ceab657` | `调用` | 同上，但使用由出资方指定的、超出租金部分的 lamport     |
| `create_pda(uint64,bytes32)`         | `0x48e2bb86` | `调用` | 带 lamport 的盐派生 PDA                |
| `create_pda(bytes32,uint64,bytes32)` | `0xcc258bbf` | `调用` | 指定所有者、大小为 N、盐派生                   |
| `allocate(uint64,bytes32)`           | `0x93225c9f` | `调用` | 在盐派生 PDA 上分配 N 字节                 |
| `assign(bytes32,bytes32)`            | `0x8ac00bdc` | `调用` | 将盐派生 PDA 分配给新所有者                  |
| `transfer(address,uint64)`           | `0x5d359fbd` | `调用` | 向 EVM 地址派生的 PDA 转账 lamport        |
| `transfer(bytes32,uint64)`           | `0xfd54d1ea` | `调用` | 向原始 Solana 公钥转账 lamport           |
| `transfer(bytes32,uint64,bytes32)`   | `0x875abfc0` | `调用` | 向原始公钥转账 lamport，源地址为盐派生           |

## SplCached（`0xff00000000000000000000000000000000000005`)

SPL Token / Token-2022 转账、ATA 初始化及跨状态账户读取，暂存至覆盖层。

| Solidity 签名                                     | 选择器          | 分派                  | 说明                                                                                                                                                       |
| ----------------------------------------------- | ------------ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transfer(address,uint256)`                     | `0xa9059cbb` | `调用`                | 调用者作为所有者的 SPL 转账，转至 EVM 地址派生 PDA 的 ATA，使用当前 Rollup 铸币                                                                                                    |
| `transfer(bytes32,uint256)`                     | `0x6a467394` | `调用`                | 同上，接收方以原始 Solana 公钥给出                                                                                                                                    |
| `transfer(address,uint256,bytes32)`             | `0x57cfeeee` | `调用`                | 显式铸币变体，EVM 地址目的地                                                                                                                                         |
| `transfer(bytes32,uint256,bytes32)`             | `0x7db527f9` | `调用`                | 显式铸币变体，原始公钥目的地                                                                                                                                           |
| `transferFrom(address,address,uint256,bytes32)` | `0x401e3367` | `调用`                | 委托源变体——权限 = `external_auth(caller)`，可作为 ATA 所有者或拥有足额额度的委托方被接受。由以下项使用： `SPL_ERC20_cached.transferFrom` 以及路由器驱动的流程                                         |
| `approve(address,uint256,bytes32)`              | `0x8180f2fc` | `调用`                | EVM 支出方授权——所有者 = `external_auth(caller)`，委托方 = `external_auth(spender_addr)`。由以下项使用： `SPL_ERC20_cached.approve`                                          |
| `mint(address,uint256,bytes32)`                 | `0x1e458bee` | `调用`                | 调用者 PDA 作为铸币权限签名。SPL 运行时强制调用者 PDA 必须等于链上铸币权限。由以下项使用： `SPL_ERC20_cached.mint_to` 以及入站桥接结算                                                                 |
| `init(bytes32,bytes32,bytes32)`                 | `0x0b0ad508` | `调用`                | `InitializeAccount3` 指令（ata、mint、owner）                                                                                                                  |
| `account(address)`                              | `0x73b9aa91` | `CrossStateEthCall` | 读取 EVM 地址的 PDA 派生 ATA 的 SPL 账户状态（当前 Rollup 铸币）                                                                                                           |
| `account(bytes32)`                              | `0x882358ae` | `CrossStateEthCall` | 读取原始 ATA 公钥的 SPL 账户状态                                                                                                                                    |
| `account(address,bytes32)`                      | `0xf9827227` | `CrossStateEthCall` | 与 `account(address)` 相同，但使用显式铸币。                                                                                                                         |
| `mint_info(bytes32)`                            | `0xe24bf5d4` | `CrossStateEthCall` | 铸币信息，感知覆盖层：代币程序、小数位数、 **已启用** 钩子程序（缺失时为 0 *或* 表示未启用）、当前纪元的费用 bps，以及扩展存在位图。与以下项使用相同选择器： `HelperProgram.mint_info` ——一项能力，两个分派入口，因为缓存轨道合约在触发缓存调用后不能使用旧版读取。 |

## ASplCached（`0xff00000000000000000000000000000000000006`)

关联代币账户创建，幂等。

| Solidity 签名                   | 选择器          | 分派   | 说明                              |
| ----------------------------- | ------------ | ---- | ------------------------------- |
| `create_ata()`                | `0xb6d336ed` | `调用` | 为调用者 PDA × 当前 Rollup 铸币创建幂等 ATA |
| `create_ata(bytes32)`         | `0x81972e35` | `调用` | 为调用者 PDA × 显式铸币创建幂等 ATA         |
| `create_ata(address)`         | `0x5a7c3259` | `调用` | 为 EVM 地址派生 PDA × 当前铸币创建幂等 ATA   |
| `create_ata(address,bytes32)` | `0x3de2251a` | `调用` | 为 EVM 地址 × 显式铸币创建幂等 ATA         |

## WithdrawCached（`0xff0000000000000000000000000000000000000b`)

Gas 代币提现环节（原生 gas → SPL 包装代币、原生 gas → SOL、原生 gas → 调用者 PDA），暂存。是旧版 `Withdraw @ 0x42..16`.

| Solidity 签名                   | 选择器          | 分派    | 说明                                                                                                                                                                                                                                                         |
| ----------------------------- | ------------ | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `withdrawal(bytes32) payable` | `0x4d8b0ea4` | `组合式` | 销毁 `msg.value` Rome gas，转账至 Solana 系统账户接收方                                                                                                                                                                                                                 |
| `withdraw_to_pda(uint256)`    | `0x7f3124a0` | `组合式` | 销毁 wei，将 lamport 存入调用者的 `EXTERNAL_AUTHORITY` PDA。仅单状态。                                                                                                                                                                                                     |
| `withdraw_to_ata(uint256)`    | `0x8059abc0` | `组合式` | 销毁 wei，将 SPL 包装代币存入调用者 PDA 所有的 ATA。仅单状态。是 gas 包装代币桥的包装环节。                                                                                                                                                                                                  |
| `deposit(uint256)`            | `0xb6b55f25` | `组合式` | 以下操作的逆操作： `withdrawal` ——在 Solana 端，从调用者 PDA 所有的 ATA 向链的 sol\_wallet ATA 进行 SPL 转账； **mint** `wei` 在 EVM 端向调用者铸造原生 gas。纯铸造（不针对以下项进行抵销扣款： `Withdraw::ADDRESS` ——链的 SPL 钱包才是经济支撑，而非预编译地址）。仅单状态。是 gas 包装代币桥的解包环节。与以下项语义一致： `HelperProgram.deposit_from_ata` 。 |

## System（`0xff00000000000000000000000000000000000007`)

PDA 派生、base58 转换和标识类实用工具。纯读取预编译合约——每个方法均为 `EthCall` （无 Solana 副作用）。

| Solidity 签名                                       | 选择器          | 分派        | 说明                                                     |
| ------------------------------------------------- | ------------ | --------- | ------------------------------------------------------ |
| `find_program_address(bytes32,(bytes)[])`         | `0x27e3edda` | `EthCall` | Solana `find_program_address` 通过系统调用——返回 `(pda, bump)` |
| `create_program_address(bytes32,(bytes)[],uint8)` | `0xb99f29e1` | `EthCall` | 使用已知 bump 的常数时间 PDA 派生                                 |
| `rome_evm_program_id()`                           | `0xb76fd45b` | `EthCall` | 返回此 Rome EVM 程序的 Solana 程序 ID                          |
| `program_id()`                                    | `0x77764881` | `EthCall` | 返回 Rome 的 System Program ID（此预编译合约的标识）                 |
| `mint_id()`                                       | `0xe132a122` | `EthCall` | 返回该链 gas 代币 SPL 铸币公钥（`OwnerInfo.chain_mint_id`)        |
| `operator()`                                      | `0x570ca735` | `EthCall` | 返回外层 Rome 交易的 Solana 签名者                               |
| `bytes32_to_base58(bytes32)`                      | `0xfa2b1a5f` | `EthCall` | 公钥字节 → base58 字符串                                      |
| `base58_to_bytes32(bytes)`                        | `0x5df01b72` | `EthCall` | base58 字符串 → 公钥字节                                      |

## CpiProgram（`0xff00000000000000000000000000000000000008`)

**双用途预编译合约。** 在下方 7 个选择器中， **2 个执行真实 Solana CPI** (`invoke`, `invoke_signed` ——按以下方式分派： `调用`）以及 **5 个是纯跨状态读取** (`account_info`, `account_data_at`, `account_u64_at`, `account_lamports`, `pdas_batch_derive` ——按以下方式分派： `CrossStateEthCall`，无系统调用，且不设置 `found_cpi` 标志）。历史术语“CPI 快捷选择器”指的是读取选择器，它们是为节省 CU 而取代早期基于 CPI 的读取的方案——它们本身 **不是 CPI**。完整行为矩阵请参见本节顶部的消歧表。

| Solidity 签名                                                    | 选择器          | 分派                  | 说明                                                                                                                     |
| -------------------------------------------------------------- | ------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `invoke(bytes32,(bytes32,bool,bool)[],bytes)`                  | `0x7480cb86` | `调用`                | CPI 以 `EXTERNAL_AUTHORITY(caller)` 身份签名，前提是该账户被列为签名者（在 DELEGATECALL 下被拒绝）；不支持带盐子 PDA。调用者传入目标程序、账户元数据和指令数据              |
| `invoke_signed(bytes32,(bytes32,bool,bool)[],bytes,bytes32[])` | `0xb94f3733` | `调用`                | CPI 以 `EXTERNAL_AUTHORITY(caller)` 在直接 CALL 上；盐会为每个 PDA 种子追加。在 DELEGATECALL 下，裸调用者权限会被拒绝，且带盐种子会携带正在运行的合约地址——请参见下方的派生说明 |
| `account_info(bytes32)`                                        | `0xc13465d9` | `CrossStateEthCall` | 读取 Solana 账户的完整状态（lamport / 所有者 / 标志 / 数据）                                                                             |
| `account_data_at(bytes32,uint16,uint16)`                       | `0x593762e8` | `CrossStateEthCall` | 读取任意 Solana 账户数据缓冲区的一个切片                                                                                               |
| `account_u64_at(bytes32,uint16)`                               | `0xb317d4c1` | `CrossStateEthCall` | 在已知偏移量处进行类型化 u64 小端读取——节省 ABI 往返                                                                                       |
| `account_lamports(bytes32)`                                    | `0xde79ed54` | `CrossStateEthCall` | 仅 lamport 探测——跳过数据获取                                                                                                   |
| `pdas_batch_derive(bytes[][],bytes32)`                         | `0x944336f8` | `CrossStateEthCall` | 在一次分派中为一个程序派生 N 个独立 PDA                                                                                                |

## HelperProgram（`0xff00000000000000000000000000000000000009`)

面向 Rome 用户的助手，用于 ATA/PDA 创建、由调用者签名的 SPL 转账/授权/铸造 `EXTERNAL_AUTHORITY` PDA、gas↔lamport 转换、ATA 存款，以及面向 SPL\_ERC20 的读取（`user_balance` / `allowance_of`）。每个方法均为 `not_payable`；变更通过以下方式路由： `调用` （单次 CPI），但以下除外： `deposit_from_ata` (`组合式`，仅单状态）、三个只读 `pda`/`ata` 查询（`EthCall`），以及两项跨状态 SPL\_ERC20 读取（`CrossStateEthCall` ——一次 Solana 账户获取）。

| Solidity 签名                                                      | 选择器          | 分派                  | 说明                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------------------------------- | ------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create_ata(address)`                                            | `0x5a7c3259` | `调用`                | 在链的 gas 铸币下为 EVM 用户创建 ATA                                                                                                                                                                                                                                                                                                          |
| `create_ata(address,bytes32)`                                    | `0x3de2251a` | `调用`                | 在任意铸币下为 EVM 用户创建 ATA                                                                                                                                                                                                                                                                                                               |
| `create_ata_for_key(bytes32,bytes32)`                            | `0xd258a69d` | `调用`                | 为任意原始 Solana 公钥作为所有者创建幂等 ATA（并非通过以下方式派生： `external_auth`）。操作员支付租金。由以下项使用： `SPL_ERC20.bridgeOutToSolana` / `ensureRecipientAta` / `create_token_account` 原始公钥接收方流程                                                                                                                                                                  |
| `create_pda(address)`                                            | `0xff3556ca` | `调用`                | 创建用户的 `EXTERNAL_AUTHORITY` PDA（免租）                                                                                                                                                                                                                                                                                                 |
| `create_pda(address,uint64)`                                     | `0x58e88298` | `调用`                | 相同，但使用以下资金 `lamports` 超过租金下限                                                                                                                                                                                                                                                                                                       |
| `swap_gas_to_lamports(uint64)`                                   | `0x6e3f24e0` | `调用`                | 向调用者的 PDA 记入 `n` 来自交易的 Solana 费用支付者的 lamports；调用者以 Rome gas 支付这些费用（在任何旧版 CPI 中，支付者消耗的 lamport 会计入交易费用）                                                                                                                                                                                                                             |
| `transfer_lamports(address,uint64)`                              | `0x5fe71665` | `调用`                | 将 lamports 从调用者的 PDA 转移到另一个 EVM 用户的 PDA                                                                                                                                                                                                                                                                                            |
| `transfer_spl(address,uint64)`                                   | `0xb12be5ba` | `调用`                | 将链气费 SPL 从调用者 PDA 的 ATA 发送到目标用户的 ATA                                                                                                                                                                                                                                                                                               |
| `transfer_spl(bytes32,uint64)`                                   | `0xba3a5eac` | `调用`                | 将链气费 SPL 从调用者 PDA 的 ATA 发送到显式指定的 ATA                                                                                                                                                                                                                                                                                               |
| `transfer_spl(address,uint64,bytes32)`                           | `0x53b505e0` | `调用`                | 将任意铸币的 SPL 从调用者 PDA 的 ATA 发送到目标用户的 ATA                                                                                                                                                                                                                                                                                             |
| `transfer_spl(bytes32,uint64,bytes32)`                           | `0xb6977879` | `调用`                | 将任意铸币的 SPL 从调用者 PDA 的 ATA 发送到显式指定的 ATA                                                                                                                                                                                                                                                                                             |
| `transfer_spl(bytes32,bytes32,uint64,bytes32)`                   | `0x766b362a` | `调用`                | 委托变体——调用者提供 `src_ata` （必须由 PDA 拥有，或者 PDA 必须是具备足够 `delegated_amount`)                                                                                                                                                                                                                                                               |
| `transfer_spl(address,address,uint64,bytes32)`                   | `0xe479df56` | `调用`                | 按地址键控的委托变体——在内部从 EVM 地址派生两个 ATA。以 `external_auth(caller)`；SPL Token 接受 PDA 作为 owner 或 delegate。由以下使用： `SPL_ERC20.transferFrom`                                                                                                                                                                                                     |
| `transfer_spl_to_signer(uint64,bytes32)`                         | `0x46efa679` | `调用`                | Solana 原生退出路径。发送 `amount` 的 `mint` 从调用者 PDA 的 ATA 到 **外部 Solana 签名者的** 该铸币的 ATA（仅在钱包签名的 Solana 通道中是用户自己的钱包；从 MetaMask 或通过中继时，签名者是 Rome 的代理支付者；不进行 EVM 地址转换）。无需 approve——调用者 PDA 拥有源 ATA。请与 `ActivateAta` （slot 18）配合，用于端到端仅使用 Solana 密钥的 EVM 场景。它可在当前 v1 通道以及较早的 legacy `DoTxUnsigned` （slot 17）通道上到达钱包，因为钱包在这两条通道上都会签署 Solana 交易。 |
| `approve_spl(address,uint64,bytes32)`                            | `0xabf6f675` | `调用`                | 由调用者 PDA 作为 owner 设置 `delegate_pda(spender)` 通过 SPL 在 owner-ATA 上 `approve_checked`。由以下项使用： `SPL_ERC20.approve`                                                                                                                                                                                                                    |
| `approve_spl_raw_delegate(bytes32,bytes32,uint64,bytes32,uint8)` | `0x7881d453` | `调用`                | SPL `approve_checked` 使用调用者提供的原始公钥委托（例如 Wormhole `authority_signer` PDA，无 EVM 地址等价物）。调用者传入 `decimals` 以跳过链上 mint 读取（节省约 30-50K CU）。硬编码 `spl_program = SPL Token`。由以下项使用： `RomeBridgeWithdraw.approveBurnETH`                                                                                                                       |
| `mint_spl(address,uint64,bytes32)`                               | `0xd795522b` | `调用`                | 由调用者 PDA 作为 mint\_authority，通过 SPL 铸造到目标用户的 ATA `mint_to_checked`。SPL 运行时强制检查权限匹配。由以下使用： `SPL_ERC20.mint_to`                                                                                                                                                                                                                       |
| `create_mint_account(bytes32)`                                   | `0xe97d3291` | `调用`                | System CreateAccount 为盐值派生的 PDA 分配空间（`external_auth_with_salt(caller, salt)`）space=82，归 SPL Token 所有。资助者 = 调用者的 external\_auth PDA。两个 PDA 签名者。由以下使用： `ERC20SPLFactory.create_token_mint`                                                                                                                                           |
| `init_spl_mint(bytes32,uint8,bytes32,bool,bytes32)`              | `0x4f75e987` | `调用`                | SPL Token `InitializeMint2` 针对预分配的 mint。没有 PDA 签名者（mint\_authority/freeze\_authority 作为数据存储，而非运行时签名者）。由以下使用： `ERC20SPLFactory.init_token_mint`                                                                                                                                                                                     |
| `create_and_init_mint(uint8,bytes32,bool,bytes32,bytes32)`       | `0x20972d0f` | `组合式`               | 组合：System CreateAccount + SPL InitializeMint2 一次分发完成。相较于单独调用，节省 1 个 Rome DoTx 封装 `create_mint_account` + `init_spl_mint` 调用                                                                                                                                                                                                        |
| `deposit_from_ata(uint256)`                                      | `0x4479b709` | `组合式`               | 将 SPL 从调用者的 ATA 提取为 Rome 原生 gas。 **仅单状态** — 在 op-geth 链上被拒绝                                                                                                                                                                                                                                                                        |
| `pda(address)`                                                   | `0x8854a299` | `EthCall`           | 派生用户的 `EXTERNAL_AUTHORITY` PDA — 只读                                                                                                                                                                                                                                                                                                |
| `pda_with_salt(address,bytes32)`                                 | `0x5c6d04b3` | `EthCall`           | 由盐值派生的 `EXTERNAL_AUTHORITY` PDA，一次分发完成。将 Solidity 侧的 2 次调用 `rome_evm_program_id() + find_program_address()` 组合折叠为一次。由以下使用： `RomeEVMAccount.pda_with_salt`, `RomeBridgeWithdraw.{burnUSDC,burnETH}`                                                                                                                                 |
| `ata(address)`                                                   | `0x31db4f82` | `EthCall`           | 派生 `getATA(user_pda, chain_mint_id)` — 组合 EXT\_AUTH + ATA — 只读                                                                                                                                                                                                                                                                     |
| `ata(address,bytes32)`                                           | `0xfeb1c647` | `EthCall`           | 与显式指定的 mint 相同 — 只读                                                                                                                                                                                                                                                                                                                |
| `user_balance(address,bytes32)`                                  | `0xdd0119c8` | `CrossStateEthCall` | 读取用户 ATA `amount` （SPL TokenAccount 偏移量 64）。如果 ATA 不存在则返回 0（链上首次探测）。将 3 个 v1 分发合并。由以下使用： `SPL_ERC20.balanceOf`                                                                                                                                                                                                                     |
| `mint_info(bytes32)`                                             | `0xe24bf5d4` | `CrossStateEthCall` | 供 legacy-track 调用者使用的 mint 事实：代币程序、decimals、 **已启用** 钩子程序（缺失时为 0 *或* 惰性）、当前 epoch 费用 bps、扩展存在位图。镜像于 `SplCached` 相同 selector 上。 `feeBps` 是一个 **谓词** ——它表示费用已启用，它不是操作数，因为实际费用受以下项上限约束 `maximum_fee` 而此处刻意不携带该项。                                                                                                                      |
| `allowance_of(address,address,bytes32)`                          | `0xed72dbc8` | `CrossStateEthCall` | 读取 owner-ATA 的 delegated\_amount，并进行 **delegate 相等性检查** ——除非链上 delegate == `external_auth(spender)`。ERC-20 语义正确（硬性要求）。由以下使用： `SPL_ERC20.allowance`                                                                                                                                                                                 |

## 提现（`0x4200000000000000000000000000000000000016`)

Rome → Solana 原生 gas 提现。

| Solidity 签名                | 选择器          | 分派                | 说明                                                           |
| -------------------------- | ------------ | ----------------- | ------------------------------------------------------------ |
| `withdrawal(bytes32)`      | `0x4d8b0ea4` | `组合式` (`payable`) | 销毁 `msg.value` Rome gas；铸造并转移到一个 Solana 系统账户 `到`。唯一可支付的预编译方法 |
| `withdraw_to_pda(uint256)` | `0x7f3124a0` | `组合式`             | 燃烧 gas；存入调用者的 `EXTERNAL_AUTHORITY` PDA。 **仅单状态**             |
| `withdraw_to_ata(uint256)` | `0x8059abc0` | `组合式`             | 燃烧 gas；存入 `getATA(caller_pda, chain_mint_id)`. **仅单状态**      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.rome.builders/zh/can-kao/precompiles.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
