# 部署 Solidity 合约

本指南介绍如何使用 Hardhat 和 Foundry 在 Rome EVM 上部署 Solidity 智能合约。

## 前置条件

* 已安装 Node.js v18+（Hardhat）或 Foundry
* 一个已充值的 Rome EVM 地址（见 [快速开始](/zh/ru-men/quickstart.md))
* 你的私钥已导出为环境变量

```bash
export PRIVATE_KEY="0xYOUR_PRIVATE_KEY"
```

## 网络配置

| 网络               | RPC URL                                      | 链 ID     |
| ---------------- | -------------------------------------------- | -------- |
| 本地               | `http://localhost:9090`                      | `1001`   |
| Devnet（montispl） | `https://montispl.devnet.romeprotocol.xyz`   | `200002` |
| Testnet（Martius） | `https://martius-i.testnet.romeprotocol.xyz` | `121214` |
| Testnet（Caelian） | `https://caelian-i.testnet.romeprotocol.xyz` | `121215` |

## Hardhat

### 设置

```bash
mkdir my-rome-project && cd my-rome-project
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init
```

### hardhat.config.js

```javascript
require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: {
    version: "0.8.28",
    settings: {
      optimizer: { enabled: true, runs: 200 },
    },
  },
  networks: {
    rome_local: {
      url: "http://localhost:9090",
      chainId: 1001,
      accounts: [process.env.PRIVATE_KEY],
    },
    rome_devnet: {
      url: "https://montispl.devnet.romeprotocol.xyz",
      chainId: 200002,
      accounts: [process.env.PRIVATE_KEY],
    },
    rome_martius: {
      url: "https://martius-i.testnet.romeprotocol.xyz",
      chainId: 121214,
      accounts: [process.env.PRIVATE_KEY],
    },
    rome_caelian: {
      url: "https://caelian-i.testnet.romeprotocol.xyz",
      chainId: 121215,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};
```

### 部署

```bash
npx hardhat run scripts/deploy.js --network rome_devnet
```

### 在区块浏览器上验证

```bash
npx hardhat verify --network rome_martius 0xCONTRACT_ADDRESS
```

## Foundry

### 设置

```bash
forge init my-rome-project
cd my-rome-project
```

### 部署

```bash
# 本地
forge create --rpc-url http://localhost:9090 \
  --private-key $PRIVATE_KEY \
  src/Counter.sol:Counter

# Devnet
forge create --rpc-url https://montispl.devnet.romeprotocol.xyz \
  --private-key $PRIVATE_KEY \
  src/Counter.sol:Counter
```

### 调用已部署合约

```bash
# 读取
cast call 0xCONTRACT_ADDRESS "number()" \
  --rpc-url https://montispl.devnet.romeprotocol.xyz

# 写入
cast send 0xCONTRACT_ADDRESS "increment()" \
  --rpc-url https://montispl.devnet.romeprotocol.xyz \
  --private-key $PRIVATE_KEY
```

## 使用 Rome Solidity SDK

对于与 Solana 程序交互的合约，请安装 Rome Solidity SDK：

```bash
npm install @rome-protocol/solidity-sdk
```

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {SplToken, CpiProgram, SystemProgram} from "@rome-protocol/solidity-sdk/contracts/core/Precompiles.sol";
import {SPL_ERC20} from "@rome-protocol/solidity-sdk/contracts/token/ERC20SPL.sol";
import {RomeEVMAccount} from "@rome-protocol/solidity-sdk/contracts/core/RomeEVMAccount.sol";

contract MyRomeContract {
    // 从 Solana 读取用户的 SPL 代币余额
    function getSolanaBalance(bytes32 mint) external view returns (uint64) {
        bytes32 userPda = RomeEVMAccount.pda(msg.sender);
        ISplToken.Account memory account = SplToken.account_state(userPda);
        return account.amount;
    }

    // 通过 CPI 调用任意 Solana 程序
    function callSolanaProgram(
        bytes32 programId,
        ICrossProgramInvocation.AccountMeta[] calldata accounts,
        bytes calldata data
    ) external {
        CpiProgram.invoke(programId, accounts, data);
    }
}
```

## 部署限制

| 约束          | 限制             | 说明                             |
| ----------- | -------------- | ------------------------------ |
| 最大合约大小      | 480 KB         | 在 OP-Geth 模式下，从以太坊的 24 KB 提升而来 |
| 交易大小限制      | 每个持有者 80 KB    | 较大的部署会透明地拆分到多个持有者账户中           |
| 计算预算        | 约 140 万 CU（原子） | 对于重型合约，请使用迭代模式                 |
| Solidity 版本 | 推荐使用 0.8.28    | 更早版本也可用，但 0.8.28 与 SDK 最匹配     |

## 常见错误

| 错误            | 原因             | 修复                                            |
| ------------- | -------------- | --------------------------------------------- |
| `gas 资金不足`    | EVM 地址没有余额     | 通过充值界面存入 SOL                                  |
| `nonce 过低`    | 钱包中的 nonce 已过期 | 重置 MetaMask 账户或手动指定 nonce                     |
| `执行被回滚`       | 合约逻辑执行失败       | 使用以下命令调试 `eth_call` 或 `forge test --fork-url` |
| `交易 gas 价格过低` | Gas 价格低于最低要求   | 提高交易中的 gas 价格                                 |

## 下一步

* [从 EVM 调用 Solana](/zh/kai-fa-zhe-zhi-nan/call-solana-from-evm.md) — 使用 CPI 预编译与 Solana 程序交互
* [代币包装](https://github.com/rome-protocol/docs/blob/main/developer-guides/token-wrapping.md) — 为 SPL 代币部署 ERC-20 包装器
* [CU 优化](https://github.com/rome-protocol/docs/blob/main/developer-guides/cu-optimization.md) — 降低计算单元消耗


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rome.builders/zh/kai-fa-zhe-zhi-nan/deploy-solidity.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
