# Deploy Solidity Contracts

This guide covers deploying Solidity smart contracts on Rome EVM using Hardhat and Foundry.

## Prerequisites

* Node.js v18+ (Hardhat) or Foundry installed
* A funded Rome EVM address (see [Quickstart](/getting-started/quickstart.md))
* Your private key exported as an environment variable

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

## Network Configuration

| Network           | RPC URL                                      | Chain ID |
| ----------------- | -------------------------------------------- | -------- |
| Local             | `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

### Setup

```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],
    },
  },
};
```

### Deploy

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

### Verify on Block Explorer

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

## Foundry

### Setup

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

### Deploy

```bash
# Local
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
```

### Call Deployed Contract

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

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

## Using the Rome Solidity SDK

For contracts that interact with Solana programs, install the 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 {
    // Read user's SPL token balance from Solana
    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;
    }

    // Invoke any Solana program via CPI
    function callSolanaProgram(
        bytes32 programId,
        ICrossProgramInvocation.AccountMeta[] calldata accounts,
        bytes calldata data
    ) external {
        CpiProgram.invoke(programId, accounts, data);
    }
}
```

## Deployment Constraints

| Constraint             | Limit              | Notes                                                        |
| ---------------------- | ------------------ | ------------------------------------------------------------ |
| Max contract size      | 480 KB             | Raised from Ethereum's 24 KB for OP-Geth mode                |
| Transaction size limit | 80 KB per holder   | Large deploys are split across holder accounts transparently |
| Compute budget         | \~1.4M CU (atomic) | Use iterative mode for heavy contracts                       |
| Solidity version       | 0.8.28 recommended | Earlier versions work but 0.8.28 matches the SDK             |

## Common Errors

| Error                        | Cause                      | Fix                                              |
| ---------------------------- | -------------------------- | ------------------------------------------------ |
| `insufficient funds for gas` | EVM address has no balance | Deposit SOL via the deposit UI                   |
| `nonce too low`              | Stale nonce in wallet      | Reset MetaMask account or specify nonce manually |
| `execution reverted`         | Contract logic failed      | Debug with `eth_call` or `forge test --fork-url` |
| `transaction underpriced`    | Gas price below minimum    | Increase gas price in transaction                |

## What's Next

* [Call Solana from EVM](/developer-guides/call-solana-from-evm.md) — use CPI precompiles to interact with Solana programs
* [Token Wrapping](https://github.com/rome-protocol/docs/blob/main/developer-guides/token-wrapping.md) — deploy ERC-20 wrappers for SPL tokens
* [CU Optimization](https://github.com/rome-protocol/docs/blob/main/developer-guides/cu-optimization.md) — reduce compute unit consumption


---

# 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/developer-guides/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.
