> 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/ko/developer-guides/deploy-solidity.md).

# Solidity 컨트랙트 배포

Hardhat 또는 Foundry로 Solana에 Solidity 스마트 계약을 배포하세요 — Rome 네트워크 구성, 자금이 준비된 계정, 단계별 배포.

이 가이드는 Hardhat과 Foundry를 사용해 Rome EVM에 Solidity 스마트 계약을 배포하는 방법을 다룹니다.

## 사전 요구 사항

* Node.js v22.13+ (Hardhat) 또는 Foundry가 설치되어 있음
* 자금이 충전된 Rome EVM 주소(참고 [빠른 시작](/ko/getting-started/quickstart.md))
* 환경 변수로 내보낸 개인 키

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

## 네트워크 설정

| 네트워크             | RPC URL                                     | 체인 ID    | 익스플로러                                  |
| ---------------- | ------------------------------------------- | -------- | -------------------------------------- |
| Hadrian(테스트넷)    | `https://hadrian.testnet.romeprotocol.xyz/` | `200010` | `via-hadrian.testnet.romeprotocol.xyz` |
| **Rubicon(메인넷)** | `https://rubicon.mainnet.romeprotocol.xyz/` | `7531`   | `via-rubicon.mainnet.romeprotocol.xyz` |

가스는 모든 네트워크에서 USDC입니다. Hadrian에서는 테스트 USDC를 브리지하거나 Solana devnet 지갑에서 래핑하여 얻습니다([수전](/ko/resources/faucets.md)); Rubicon에서는 Ethereum에서 USDC를 브리지하여 [Rome Bridge](https://bridge-api.mainnet.romeprotocol.xyz/)을 사용합니다. Hadrian에서 테스트한 것과 동일한 아티팩트로 Rubicon에 배포하세요. 체인 ID와 래퍼 주소만 다릅니다.

## Hardhat

### 설정

```bash
mkdir my-rome-project && cd my-rome-project
npx hardhat --init
```

기본값을 수락하세요(Hardhat 3, 현재 디렉터리, TypeScript + viem 템플릿); 의존성은 자동으로 설치됩니다.

### hardhat.config.ts

```typescript
import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem";
import { configVariable, defineConfig } from "hardhat/config";

export default defineConfig({
  plugins: [hardhatToolboxViemPlugin],
  solidity: {
    profiles: {
      default: { version: "0.8.28" },
      production: {
        version: "0.8.28",
        settings: { optimizer: { enabled: true, runs: 200 } },
      },
    },
  },
  networks: {
    hadrian: {
      type: "http",
      chainType: "l1",
      chainId: 200010,
      url: "https://hadrian.testnet.romeprotocol.xyz/",
      accounts: [configVariable("PRIVATE_KEY")],
    },
    rubicon: {
      type: "http",
      chainType: "l1",
      chainId: 7531,
      url: "https://rubicon.mainnet.romeprotocol.xyz/",
      accounts: [configVariable("PRIVATE_KEY")],
    },
  },
});
```

`configVariable("PRIVATE_KEY")` 환경(또는 암호화된 키 저장소에서) 확인됩니다 — `npx hardhat keystore set PRIVATE_KEY`).

### 배포

```bash
npx hardhat run scripts/deploy.ts --network hadrian
```

### 블록 탐색기에서 확인

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

에서 Sourcify 검증기 구성이 필요합니다 [컨트랙트 검증](/ko/developer-guides/verify-contracts.md) 당신의 `hardhat.config.ts`.

## Foundry

### 설정

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

### 배포

```bash
# 테스트넷
forge create --rpc-url https://hadrian.testnet.romeprotocol.xyz/ \
  --private-key $PRIVATE_KEY \
  src/Counter.sol:Counter
```

### 배포된 계약 호출

```bash
# 읽기
cast call 0xCONTRACT_ADDRESS "number()" \
  --rpc-url https://hadrian.testnet.romeprotocol.xyz/

# 쓰기
cast send 0xCONTRACT_ADDRESS "increment()" \
  --rpc-url https://hadrian.testnet.romeprotocol.xyz/ \
  --private-key $PRIVATE_KEY
```

## Rome Solidity SDK 사용하기

Solana 프로그램과 상호작용하는 계약의 경우, 공개 [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) 저장소의 인터페이스를 사용하세요. 이는 npm이 아니라 GitHub에서 설치됩니다:

```bash
# Hardhat / npm
npm install github:rome-protocol/rome-solidity

# Foundry
forge install rome-protocol/rome-solidity
# 그런 다음 foundry.toml의 [profile.default] 아래에:
# remappings = ["@rome-protocol/rome-solidity/=lib/rome-solidity/"]
```

이외의 계약들 `interface.sol` 및 오라클 인터페이스(예: ERC-20 래퍼와 팩토리)는 OpenZeppelin을 가져옵니다. npm을 사용하면 의존성으로 함께 설치됩니다. Foundry를 사용할 경우 다음도 실행하세요 `forge install OpenZeppelin/openzeppelin-contracts` 그리고 리매핑을 추가하세요 `@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/`.

npm을 사용하면 패키지가 `@rome-protocol/rome-solidity`로 설치되므로 아래 import는 `node_modules`에서 확인됩니다. Foundry를 사용하면 리매핑으로 동일한 import가 `lib/rome-solidity`.

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

import {ICrossProgramInvocation, IHelperProgram}
    from "@rome-protocol/rome-solidity/contracts/interface.sol";

contract MyRomeContract {
    IHelperProgram constant Helper =
        IHelperProgram(0xFF00000000000000000000000000000000000009);
    ICrossProgramInvocation constant Cpi =
        ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);

    // 호출자의 PDA에서 SPL 토큰을 전송
    function moveSpl(address to, uint64 tokens, bytes32 mint) external {
        Helper.transfer_spl(to, tokens, mint);
    }

    // CPI를 통해 임의의 Solana 프로그램 호출
    function callSolanaProgram(
        bytes32 programId,
        ICrossProgramInvocation.AccountMeta[] calldata accounts,
        bytes calldata data
    ) external {
        Cpi.invoke(programId, accounts, data);
    }
}
```

## 기존 프로토콜을 가져오기

어떤 Solidity 계약이든 Rome에 수정 없이 배포됩니다 — 컴플라이언스 계약, DeFi 프로토콜 또는 기존의 검증된 애플리케이션. 당신의 계약에 없는 유일한 것은 **한 번만 필요한 래퍼 승인**: 사용자가 당신의 계약을 통해 SPL 래퍼 토큰(wUSDC 등)을 이동하려면, 첫 `transferFrom`전에 해당 토큰의 래퍼가 자신의 토큰을 한 번 이동할 수 있는 권한을 부여해야 합니다. 그렇지 않으면 전송은 SPL 오류 `0x4`. 확인하라 `isEnabled(user)` 에서 되돌아가며 [지갑당 1회 권한 부여](/ko/core-concepts/token-interop.md#one-time-grant-per-wallet)를 보게 됩니다. 프런트엔드가 승인을 보내고 계약은 변경되지 않습니다. 아래의 동일한 Hardhat / Foundry 흐름으로 포크하고 배포할 수 있는 두 가지 프로덕션 예시:

* [**compound-on-rome-comet**](https://github.com/rome-protocol/compound-on-rome-comet) — 표준 Foundry를 사용하는 정식 Compound v3(Comet).
* [**rome-aave-v3**](https://github.com/rome-protocol/rome-aave-v3) — 정식 Aave v3.

둘 다 계약 변경 없이 Solana 실행 및 CPI 조합성을 얻습니다. 사용자는 첫 입금 전에 위에서 설명한 1회용 래퍼 승인을 수행합니다.

## 가스

도구가 가스를 추정하도록 하세요(`eth_estimateGas`; Hardhat, `forge create` 및 `cast` 모두 수행) 그리고 `21000`를 하드코딩하지 마세요. Rome에서는 쓰기 비용의 대부분이 배포된 계약, 새 토큰 계정, 아직 사용되지 않은 수신자와 같은 Solana 계정을 생성하는 데 사용되며, 추정치에 이 비용이 포함됩니다. Solana CPI를 수행하는 호출의 경우 추정치가 낮게 나올 수 있으므로 여유를 두세요. Rome는 실제로 사용된 가스만 청구합니다. Hadrian에서 측정한 결과, 10바이트 계약 배포는 1,147,921 가스로 추정 및 사용되었고, 기존 주소로의 네이티브 전송은 21,000으로 추정되어 10,001이 사용되었습니다. 실제 계약은 더 많은 비용이 들므로 직접 배포를 추정하세요.  [JSON-RPC 페이지](/ko/reference/json-rpc.md#gas-is-solana-derived-estimate-dont-hardcode) 에 측정 표가 있습니다.

## 배포 제한

| 제약          | 한계             | 참고                               |
| ----------- | -------------- | -------------------------------- |
| 최대 계약 크기    | 24 KB          | Ethereum과 동일(EIP-170, 24,576바이트) |
| 트랜잭션 크기 제한  | 보유자당 80 KB     | 대규모 배포는 보유자 계정에 투명하게 분할됩니다       |
| 컴퓨트 예산      | \~1.4M CU(원자적) | 무거운 계약에는 반복 모드를 사용하세요            |
| Solidity 버전 | 0.8.28 권장      | 이전 버전도 작동하지만 0.8.28이 SDK와 일치합니다  |

## 일반적인 오류

| 오류                                          | 원인                                                 | 해결                                                                                                                                                                                                        |
| ------------------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `가스 잔액이 부족합니다`                              | EVM 주소에 가스 토큰이 없습니다                                | Hadrian: 테스트 USDC를 [Rome Bridge](/ko/rome/bridge-api.md) (참조 [빠른 시작](/ko/getting-started/quickstart.md)로 브리지하세요, 2단계); Rubicon: 실제 USDC를 [메인넷의 Rome Bridge](https://bridge-api.mainnet.romeprotocol.xyz/) |
| `nonce가 너무 낮음`                              | 지갑의 nonce가 오래됨                                     | MetaMask 계정을 초기화하거나 nonce를 수동으로 지정하세요                                                                                                                                                                     |
| `실행이 되돌려졌습니다`                               | 계약 로직 실패                                           | 다음으로 디버그하세요 `eth_call` 또는 `forge test --fork-url`                                                                                                                                                         |
| `실행이 되돌려졌습니다` SPL 오류와 함께 `0x4` 래퍼 토큰을 이동할 때 | 사용자가 1회용 래퍼 승인을 하지 않았습니다                           | 다음을 확인하세요 `isEnabled(user)` 에서 래퍼를 선택하고 `approve_spl` 한 번 보내세요([자세한 내용](/ko/core-concepts/token-interop.md#one-time-grant-per-wallet))                                                                    |
| `트랜잭션 가스 가격이 너무 낮음`                         | 가스 가격이 최소값보다 낮음                                    | 트랜잭션의 가스 가격을 높이세요                                                                                                                                                                                         |
| 전송 또는 배포가 고정 가스 한도로 실패함                     | 다음과 같은 하드코딩된 한도는 `21000` Solana 계정을 생성하는 비용보다 낮습니다 | 제거하고 `eth_estimateGas`                                                                                                                                                                                    |

## 다음 단계

* [컨트랙트를 Solana 사용자에게 공개하기](/ko/developer-guides/open-to-solana-users.md) 를 사용하세요 — Solana 지갑 사용자가 방금 배포한 것을 호출하도록 하세요
* [EVM에서 Solana 호출](/ko/developer-guides/call-solana-from-evm.md) 를 사용하세요 — CPI 프리컴파일을 사용해 Solana 프로그램과 상호작용하세요
* [컨트랙트 검증](/ko/developer-guides/verify-contracts.md) 를 사용하세요 — 소스 코드를 블록 탐색기에 게시하세요


---

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