데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      Foundry 이더리움 스마트 컨트랙트 개발툴 소개

      Goku 25.03.07
      2,685 5 1
      DEVOTEE 요약
      Foundry는 이더리움 계열 스마트 컨트랙트를 개발하기 위한 도구 체인으로, 의존성 관리, 프로젝트 컴파일, 테스트 실행, 배포 및 체인과의 상호작용을 지원합니다. 간단한 설치 방법은 curl 명령어를 사용하여 foundryup을 설치하고, forge, cast, anvil, chisel 등의 바이너리 파일을 포함합니다. 설치 후 워크 스페이스를 설정하고, ERC20 컨트랙트를 작성 및 배포하며, cast 명령어를 통해 스마트 컨트랙트의 함수 호출을 처리할 수 있습니다.

      소개

      이더리움 계열 스마트 컨트랙트를 개발하는 툴로 많이 사용되는 Foundry의 기능을 간단하게 소개드리겠습니다.

      Foundry 공식 홈페이지 소개글

      Foundry is a smart contract development toolchain.
      
      Foundry manages your dependencies, compiles your project, runs tests, deploys, and lets you interact with the chain from the command-line and via Solidity scripts.


      설치

      홈페이지에서는 소스코드 빌드, Docker 이미지 이용 등 여러가지 방법을 소개하고 있지만 가장 간단하게 설치 및 설정을 할 수 있는 방법을 소개하겠습니다.

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

      위 명령어를 사용하면 foundryup이 설치되면서 forge, cast, anvil, chisel 바이너리 파일이 같이 설치됩니다.

      • forge : Ethereum testing framework (like Truffle, Hardhat and DappTools).

      • cast : Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data

      • anvil : Local Ethereum node, akin to Ganache, Hardhat Network.

      • chisel : Fast, utilitarian, and verbose solidity REPL.


      워크스페이스 구성 및 실행

      워크 스페이스 생성

      $ forge init devocean
      $ cd devocean
      • 위 명령어를 사용하면 기본적인 프로젝트가 생성됩니다.

      프로젝트 빌드

      $ forge build
      [⠊] Compiling...
      [⠘] Compiling 27 files with Solc 0.8.26
      [⠃] Solc 0.8.26 finished in 749.20ms
      • 기본 생성된 컨트랙트가 빌드되고 out / cache 디렉토리가 생성

      • out : contract artifact (ABI) 를 담고 있음

      • cache : forge에서 사용하는 캐시

      테스트 코드 실행

      $ forge test
      [⠊] Compiling...
      No files changed, compilation skipped
      
      Ran 2 tests for test/Counter.t.sol:CounterTest
      [PASS] testFuzz_SetNumber(uint256) (runs: 256, μ: 31199, ~: 31277)
      [PASS] test_Increment() (gas: 31293)
      Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 5.72ms (4.78ms CPU time)
      
      Ran 1 test suite in 183.01ms (5.72ms CPU time): 2 tests passed, 0 failed, 0 skipped (2 total tests)


      컨트랙트 작성

      간단한 예시를 위해 Openzepplin에서 제공하는 기능을 사용하여 간단한 컨트랙트를 작성하겠습니다.

      컨트랙트 작성

      // SPDX-License-Identifier: MIT
      // Compatible with OpenZeppelin Contracts ^5.0.0
      pragma solidity ^0.8.22;
      
      import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
      import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
      
      contract DragonERC20 is ERC20, Ownable {
          constructor(address initialOwner)
              ERC20("DRAGON", "D")
              Ownable(initialOwner)
          {}
      
          function mint(address to, uint256 amount) public onlyOwner {
              _mint(to, amount);
          }
      }
      • 드래곤이라는 ERC20 작성

      • 위 코드로 워크스페이스 src에 DragonERC20.sol 생성

      ❗️파일을 생성한 후 다시 빌드 명령어를 입력하면 openzepplin의 파일을 찾을 수 없다는 에러가 발생합니다.❗️

      Error: Compiler run failed:
      Error (6275): Source "@openzeppelin/contracts/token/ERC20/ERC20.sol" not found: File not found. 
      • openzepplin/contract 라이브러리 설치가 필요

      라이브러리 설치

      $ forge install openzeppelin/openzeppelin-contracts --no-commit #bad
      $ forge install openzeppelin/openzeppelin-contracts@v5.1.0 --no-commit #good

      위 명령어를 입력하면 lib 디렉토리에 설치되고 버전을 명시하는 것이 좋음 (즉, 코드에서도 필요한 버전을 명시해주는 것이 좋음)

      // SPDX-License-Identifier: MIT
      // Compatible with OpenZeppelin Contracts ^5.0.0
      pragma solidity ^0.8.22;
      
      import {ERC20} from "@openzeppelin/contracts@v5.1.0/token/ERC20/ERC20.sol";
      import {Ownable} from "@openzeppelin/contracts@v5.1.0/access/Ownable.sol";
      
      ... 이하 동일 코드

      라이브러리 위치 매핑 (remappings.txt 작성)

      @openzeppelin/contracts@v5.1.0/=lib/openzeppelin-contracts/contracts/

      위 작업까지 진행하면 배포될 준비가 되었습니다. (상용환경에서는 테스트 코드 작성 필수❗️)


      컨트랙트 배포

      컨트랙트를 배포하기 위해서는 지갑과 배포를 하기 위해 필요한 가스가 필요합니다.

      쉽게 테스트 가스(코인)을 얻을 수 있는 Avalanche Testnet(FUJI)에 배포를 진행해보겠습니다.

      이더리움 계열 지갑을 생성하고 FUJI Faucet 에서 가스비를 충당합니다.

      $ forge create --broadcast --rpc-url=https://api.avax-test.network/ext/bc/C/rpc --private-key=${PRIVATE_KEY} src/DragonERC20.sol:DragonERC20 --constructor-args=0x7b7074146761Af8F8b10aB9BDA2D12613a2396E5
      [⠊] Compiling...
      No files changed, compilation skipped
      Deployer: 0x7b7074146761Af8F8b10aB9BDA2D12613a2396E5
      Deployed to: 0x5fc153596Fa7793564315800B9B37DF6f8976FDE
      Transaction hash: 0xa7260ca44145db621f2720839856c4a39913ddc97888cc6a20547a49b9dfcfcd

      flag 확인

      • rpc-url : 블록체인 노드 RPC URL

      • private-key : 지갑의 프라이빗키 (서명을 위해 필요)

      • constructor-args : 스마트 컨트랙트의 생성자 파라미터

      결과 확인

      • Deployer : transaction sender

      • Deployed to : 배포된 컨트랙트 주소

      • Transaction Hash : 블록에 생성된 transaction hash

      배포 결과 확인

      rpc call을 통해 확인을 할 수도 있고 다양한 방법이 존재하지만 간단하게 익스플로어에서 배포된 주소에 대해서 확인을 해본다. - link

      스크린샷 2024-11-30 오전 2.20.28.png

      컨트랙트 호출

      ERC20에는 소유한 토큰을 조회하는 balanceOf 함수가 존재

          /**
           * @dev Returns the value of tokens owned by `account`.
           */
          function balanceOf(address account) external view returns (uint256);

      작성한 DragonERC20에는 토큰을 발행하는 mint 함수가 존재

      function mint(address to, uint256 amount) public onlyOwner {
              _mint(to, amount);
      }

      해당 함수를 호출하기 위해서는 Contract의 소유주여야 함 (onlyOwner)

      balanceOf는 단순 조회하는 함수여서 Transaction이 발생하지 않아도 되고 mint는 상태값을 바꾸는 함수라 Transaction이 발생해야 합니다.


      cast를 이용하여 balanceOf 함수 호출 (non-tx)

      $ cast call 0x5fc153596Fa7793564315800B9B37DF6f8976FDE "balanceOf(address)(uint256)" 0x7b7074146761Af8F8b10aB9BDA2D12613a2396E5 --rpc-url=https://api.avax-test.network/ext/bc/C/rpc
      0
      • cast call 은 컨트랙트 조회하는 함수를 이용할 때 사용

      • cast call ${CONTRACT_ADDRESS} ${CALL_METHOD_INTERFACE} ${CALL_METHOD_ARGS..}

      cast를 이용한 mint 함수 호출 (tx)

      $ cast send 0x5fc153596Fa7793564315800B9B37DF6f8976FDE "mint(address,uint256)" 0x7b7074146761Af8F8b10aB9BDA2D12613a2396E5 10000000000 --rpc-url=https://api.avax-test.network/ext/bc/C/rpc --private-key=${PRIVATE_KEY}
      
      blockHash               0x5811bb810a3d51903639866742b60d8a550b142b269881cf71884f70236d02ff
      blockNumber             36912969
      contractAddress         
      cumulativeGasUsed       197009
      effectiveGasPrice       1100000001
      from                    0x7b7074146761Af8F8b10aB9BDA2D12613a2396E5
      gasUsed                 70667
      logs                    [{"address":"0x5fc153596fa7793564315800b9b37df6f8976fde","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000007b7074146761af8f8b10ab9bda2d12613a2396e5"],"data":"0x00000000000000000000000000000000000000000000000000000002540be400","blockHash":"0x5811bb810a3d51903639866742b60d8a550b142b269881cf71884f70236d02ff","blockNumber":"0x2333f49","transactionHash":"0x267be67d52ec217497062df33cac0f036e399d370e03658a38b171f82ba706de","transactionIndex":"0x1","logIndex":"0x3","removed":false}]
      logsBloom               0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000020000000000000000000800010000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000400000000000000000000000010000000000000000000000020000008000000000010000000000000000100000000000000000000000000000000
      root                    
      status                  1 (success)
      transactionHash         0x267be67d52ec217497062df33cac0f036e399d370e03658a38b171f82ba706de
      transactionIndex        1
      type                    2
      blobGasPrice            
      blobGasUsed             
      authorizationList       
      to                      0x5fc153596Fa7793564315800B9B37DF6f8976FDE
      • cast send의 경우 transaction을 발생시키기 때문에 서명을 할 수 있는 privatekey가 필요합니다.

      • cast send 호출에 성공하면 해당 transaction에 대한 기본 정보값을 반환해줍니다.

      다시 한번 balanceOf 함수 호출

      $ cast call 0x5fc153596Fa7793564315800B9B37DF6f8976FDE "balanceOf(address)(uint256)" 0x7b7074146761Af8F8b10aB9BDA2D12613a2396E5 --rpc-url=https://api.avax-test.network/ext/bc/C/rpc
      10000000000 [1e10]

      정상적으로 minting 된 것을 확인할 수 있습니다.


      익스플로어 확인

      스크린샷 2024-11-30 오전 2.35.30.png


      마무리

      Foundry는 위에서 소개한 기능외에도 정말 많은 기능을 제공하고 있는 개발툴입니다.

      특히 Solidity 테스트 코드를 작성하고 진행하는데 큰 도움을 줄 수 있는 도구입니다.

      홈페이지와 github에서 자세히 알아볼 수 있습니다.


      ref - https://book.getfoundry.sh

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      Goku 님의 최신 블로그

      더보기
      동영상 기고하기