Foundry로 개발하기
GIWA에서 Foundry를 사용해 스마트 컨트랙트를 개발하고 배포해요.
Foundry는 Ethereum Application을 개발할 때 유용하게 사용할 수 있는 Toolkit 이에요. 빠르고 모듈러 구조를 가지고 있는 것이 특징이에요. Foundry를 설치하면 아래와 같은 네 가지의 개발 핵심 도구를 사용할 수 있어요.
forge
: 스마트 컨트랙트 개발, 테스트, 배포 및 검증anvil
: 네트워크 Forking이 가능한 로컬 Ethereum 개발 노드 실행cast
: 컨트랙트 상호작용, 트랜잭션 전송 및 체인 데이터 조회chisel
: 빠른 프로토타이핑과 디버깅을 위한 Solidity REPL
개발 환경 세팅
Foundry를 먼저 설치해요.
curl -L https://foundry.paradigm.xyz | bash
foundryup
Foundry 툴킷이 모두 설치되었다면, forge
툴을 이용해서 Solidity Project를 생성할 수 있어요.
forge init giwa_project
cd giwa_project
생성된 giwa_project
는 아래와 같은 구조를 가져요.
giwa_project/
├── foundry.toml # 프로젝트 설정이 담겨있는 파일
├── lib # 프로젝트에서 사용하는 외부 라이브러리
├── script # 배포, 시뮬레이션 등을 위한 스크립트
├── src # 프로젝트 소스 코드 디렉토리
└── test # 작성한 컨트랙트 테스트를 위한 디렉토리
컨트랙트 작성하기
아주 간단한 컨트랙트부터 작성해볼까요?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
contract Giwa {
event HelloGiwa();
function helloGiwa() public {
emit HelloGiwa();
}
}
위 스마트 컨트랙트 코드는 Giwa
라는 이름의 컨트랙트이고, helloGiwa
라는 함수와 HelloGiwa
라는 이벤트를 가진 컨트랙트예요.
앞서 소개했듯, 고수준의 Solidity 코드를 저수준의 바이트코드로 컴파일되어야 EVM 위에서 실행할 수 있어요. 아래 명령어를 통해 컴파일을 할 수 있어요.
forge build
테스트 코드 작성하기
작성한 이 컨트랙트가 의도한대로 동작하는지 확인하기 위해 테스트 코드를 작성힐 수 있어요. forge
는 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();
}
}
결과를 확인하려면 아래와 같이 입력하면 돼요.
forge test
아래와 같이 결과가 나왔다면, 우리가 작성한 테스트가 통과했다는 뜻이예요.
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)
컨트랙트 배포하기
forge
는 체인과 상호작용하거나 컨트랙트를 배포할 때 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();
}
}
체인에 배포하기 위해서, 아래와 같이 환경변수 설정을 해야해요.
GIWA_SEPOLIA_RPC_URL=https://sepolia-rpc.giwa.io
BLOCKSCOUT_API_URL=https://sepolia-explorer.giwa.io/api
그리고 배포에 사용할 지갑을 cast
를 통해 Import 할 수 있어요.
cast wallet import deployer --interactive
배포는 위에 작성한 스크립트를 실행해서 진행할 수 있어요. 아래와 같이 입력해서 스크립트를 실행해요.
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 를 통해서 컨트랙트와 바로 상호작용할 수 있어요.

더 알아보기
Foundry Book 을 통해 더 많은 가이드를 읽어보세요.
Last updated