> For the complete documentation index, see [llms.txt](https://docs.giwa.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.giwa.io/get-started/smart-contract/develop/foundry.md).

# Foundry로 개발하기

[Foundry](https://getfoundry.sh/)는 Ethereum Application을 개발할 때 유용하게 사용할 수 있는 Toolkit 이에요. 빠르고 모듈러 구조를 가지고 있는 것이 특징이에요.  Foundry를 설치하면 아래와 같은  네 가지의 개발 핵심 도구를 사용할 수 있어요.

* `forge`: 스마트 컨트랙트 개발, 테스트, 배포 및 검증
* `anvil`: 네트워크 Forking이 가능한 로컬 Ethereum 개발 노드 실행
* `cast`: 컨트랙트 상호작용, 트랜잭션 전송 및 체인 데이터 조회
* `chisel`: 빠른 프로토타이핑과 디버깅을 위한 Solidity REPL

***

## 개발 환경 세팅

Foundry를 먼저 설치해요.

```bash
curl -L https://foundry.paradigm.xyz | bash
foundryup
```

Foundry 툴킷이 모두 설치되었다면, `forge` 툴을 이용해서 Solidity Project를 생성할 수 있어요.

```bash
forge init giwa_project
cd giwa_project
```

생성된 `giwa_project` 는 아래와 같은 구조를 가져요.

```
giwa_project/
├── foundry.toml    # 프로젝트 설정이 담겨있는 파일
├── lib             # 프로젝트에서 사용하는 외부 라이브러리
├── script          # 배포, 시뮬레이션 등을 위한 스크립트
├── src             # 프로젝트 소스 코드 디렉토리
└── test            # 작성한 컨트랙트 테스트를 위한 디렉토리
```

***

## 컨트랙트 작성하기

아주 간단한 컨트랙트부터 작성해볼까요?

{% code title="src/Giwa.sol" lineNumbers="true" fullWidth="false" %}

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

contract Giwa {
    event HelloGiwa();

    function helloGiwa() public {
        emit HelloGiwa();
    }
}

```

{% endcode %}

위 스마트 컨트랙트 코드는 `Giwa` 라는 이름의 컨트랙트이고, `helloGiwa` 라는 함수와 `HelloGiwa`라는 이벤트를 가진 컨트랙트예요.&#x20;

앞서 [소개](/get-started/smart-contract/develop.md)했듯, 고수준의 Solidity 코드를 저수준의 바이트코드로 컴파일되어야 EVM 위에서 실행할 수 있어요. 아래 명령어를 통해 컴파일을 할 수 있어요.

```
forge build
```

### 테스트 코드 작성하기

작성한 이 컨트랙트가 의도한대로 동작하는지 확인하기 위해 테스트 코드를 작성힐 수 있어요. `forge`는 Solidity 코드 형태로 테스트 코드를 작성할 수 있어요.

{% code title="test/Giwa.t.sol" lineNumbers="true" %}

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

import {Test} from "forge-std/Test.sol";
import {Giwa} from "../src/Giwa.sol";

contract GiwaTest is Test {
    Giwa public giwa;

    function setUp() public {
        giwa = new Giwa();
    }

    function test_helloGiwa() public {
        vm.expectEmit(true, true, true, true);
        emit Giwa.HelloGiwa();

        giwa.helloGiwa();
    }
}

```

{% endcode %}

결과를 확인하려면 아래와 같이 입력하면 돼요.

```
forge test
```

아래와 같이 결과가 나왔다면, 우리가 작성한 테스트가 통과했다는 뜻이예요.

{% code overflow="wrap" %}

```bash
Ran 1 test for test/Giwa.t.sol:GiwaTest
[PASS] test_helloGiwa() (gas: 10198)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 349.71µs (67.58µs CPU time)

Ran 1 test suite in 118.78ms (349.71µs CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)
```

{% endcode %}

***

## 컨트랙트 배포하기

`forge`는 체인과 상호작용하거나 컨트랙트를 배포할 때 Solidity 형태로 스크립트 작성할 수 있어요.&#x20;

{% code title="script/Deploy.s.sol" lineNumbers="true" %}

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

import {Script} from "forge-std/Script.sol";
import {Giwa} from "../src/Giwa.sol";

contract GiwaScript is Script {
    Giwa public giwa;

    function setUp() public {}

    function run() public {
        vm.startBroadcast();
        giwa = new Giwa();
        vm.stopBroadcast();
    }
}

```

{% endcode %}

{% hint style="info" %}
별도 배포스크립트를 작성하지 않고 `forge create` 명령어를 통해 바로 배포할 수도 있어요.

한번에 여러 컨트랙트를 배포하거나 복잡한 배포 로직을 가지는 경우 위처럼 배포스크립트를 작성해서 관리하는 것이 좋아요.
{% endhint %}

체인에 배포하기 위해서, 아래와 같이 환경변수 설정을 해야해요.

{% code title=".env" %}

```
GIWA_SEPOLIA_RPC_URL=https://sepolia-rpc.giwa.io
BLOCKSCOUT_API_URL=https://sepolia-explorer.giwa.io/api
```

{% endcode %}

그리고 배포에 사용할 지갑을 `cast`를 통해 Import 할 수 있어요.

```bash
cast wallet import deployer --interactive
```

배포는 위에 작성한 스크립트를 실행해서 진행할 수 있어요. 아래와 같이 입력해서 스크립트를 실행해요.

{% hint style="info" %}
가스비가 부족한가요? [테스트 ETH](/get-started/faucets.md)를 클레임하세요.
{% endhint %}

```bash
source .env

forge script \
    script/Deploy.s.sol \
    --account deployer \
    --rpc-url $GIWA_SEPOLIA_RPC_URL \
    --broadcast \
    --verify \
    --verifier blockscout \
    --verifier-url $BLOCKSCOUT_API_URL
```

잘 수행되었다면 아래와 같은 결과가 출력될 거예요.

```
Script ran successfully.

## Setting up 1 EVM.

==========================

Chain 91342

Estimated gas price: 0.000000505 gwei

Estimated total gas used for script: 111632

Estimated amount required: 0.00000000005637416 ETH

==========================

##### 91342
✅  [Success] Hash: <tx-hash>
Contract Address: <your-contract-address>
Block: 19449984
Paid: 0.000000000021725363 ETH (85871 gas * 0.000000253 gwei)

✅ Sequence #1 on 91342 | Total Paid: 0.000000000021725363 ETH (85871 gas * avg 0.000000253 gwei)


==========================

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
##
Start verification for (1) contracts
Start verifying contract `<your-contract-address>` deployed on 91342
EVM version: prague
Compiler version: 0.8.28

Submitting verification for [src/Giwa.sol:Giwa] <your-contract-address>.
Submitted contract for verification:
	Response: `OK`
	GUID: ``
	URL: https://sepolia-explorer.giwa.io/address/<your-contract-address>
Contract verification status:
Response: `OK`
Details: `Pass - Verified`
Contract successfully verified
All (1) contracts were verified!
```

위와 출력에서 컨트랙트 주소를 확인하고, 익스플로러를 통해 컨트랙트가 잘 배포되었는지 확인할 수 있어요. 컨트랙트 배포와 검증이 잘 이루어졌으면 익스플로러 UI 를 통해서 컨트랙트와 바로 상호작용할 수 있어요.

<div data-full-width="false"><figure><img src="/files/KLXXnCc9hc8ueunmLglu" alt=""><figcaption></figcaption></figure></div>

***

## 더 알아보기

[Foundry Book](https://getfoundry.sh/) 을 통해 더 많은 가이드를 읽어보세요.


---

# 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 dynamically by asking a question.

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

```
GET https://docs.giwa.io/get-started/smart-contract/develop/foundry.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.
