Hardhat
✏️ Hardhat
Hardhat은 이더리움 소프트웨어를 위한 개발 환경입니다. 스마트 계약 및 dApp을 편집, 컴파일, 디버깅 및 배포하기 위한 다양한 요소로 구성되며, 모두 함께 작동하여 완전한 개발 환경을 만듭니다.
🤔 Hardhat 기능
1️⃣ 테스팅 환경
Hardhat은 테스트 환경을 설정하고 테스트 코드를 작성하는데 큰 편의를 제공합니다. Mocha와 Chai를 기본적으로 지원하며, 테스트 케이스 작성, 실행, 결과 보고 등을 간편하게 수행할 수 있습니다. 또한 스마트 컨트랙트의 함수를 테스트하기 위해 Hardhat EVM을 사용하여 로컬 블록체인에서 테스트를 실행할 수 있습니다.
💡 Mocha
Mocha는 Javascript 프레임워크로, 테스트 코드를 작성하고 실행하기 위한 기능들을 제공합니다.
💡 Mocha 특징
1️⃣ Describe & It
테스트 케이스를 작성할 때 describe와 it을 사용하여 테스트 그룹과 테스트 케이스를 구성합니다.
2️⃣ Hooks
before, after, beforeEach, afterEach와 같은 훅을 사용하여 테스트 실행 전후에 필요한 설정이나 정리 작업을 수행할 수 있습니다.
3️⃣ 비동기 테스트
비동기 코드를 테스트하는데 유용한 done 콜백이나 async/await을 지원합니다.
💡 Chai
Chai는 Mocha와 함께 사용되는 BDD/TDD 스타일의 어설션 라이브러리입니다. 테스트 결과를 평가하고 비교하는데 사용되며, 다양한 어설션 스타일을 제공하여 테스트 코드를 더 읽기 쉽고 간결하게 만들어 줍니다.
💡 Chai 어설션
1️⃣ expect
자연스럽고 읽기 쉬운 BDD 스타일의 어설션을 제공합니다. expect 키워드로 시작하여 예상 결과와 비교하여 테스트를 작성할 수 있습니다.
2️⃣ should
BDD 스타일의 어설션으로, 객체가 특정 속성을 가져야한다는 것을 가독성 좋게 작성할 수 있습니다.
3️⃣ assert
TDD 스타일의 어설션으로, Node.js의 내장 assert 모듈과 유사한 구문을 가지고 있습니다.
💡 BDD (Behavior-Driven Development)
BDD는 소프트웨어의 동작 방식을 강조하는 개발 방법론입니다. BDD에서는 소프트웨어의 기능이나 행위에 대한 테스트를 작성하는
것이 중요하며, 테스트를 통해 기능이 어떻게 동작해야 하는지를 명확하게 정의합니다.
🟠 BDD 특징
1️⃣ Given-When-Then 구조
BDD 테스트 케이스는 일반적으로 테스트의 상황(Given), 액션(When), 기대 결과(Then)를 명확하게 작성하여 테스트의 목적을 이해하기 쉽게 합니다.
2️⃣ 비즈니스 요구사항과 사용자 시나리오 중심
BDD는 비즈니스 요구사항과 사용자 시나리오를 테스트로 반영하여 기능의 목적과 기대 결과를 명확하게 정의합니다.
3️⃣ 사용자 친화적 언어
BDD는 자연어에 가까운 문법과 어휘를 사용하여 테스트 케이스를 작성하므로 개발자가 이해하기 쉽습니다.
💡 TDD (Test-Driven Development)
TDD는 테스트 주도 개발로서, 테스트 코드를 먼저 작성하고 그에 해당하는 기능 코드를 개발하는 방법론입니다. TDD에서는 개발자가 요구되는 기능의 동작을 정확하게 이해하고 그에 맞는 테스트 케이스를 작성한 후에 기능 코드를 개발합니다.
🟠 TDD의 주요 단계
1️⃣ 테스트 작성 단계
개발자는 요구사항에 기반하여 테스트 케이스를 작성합니다. 이때, 아직 개발되지 않은 기능이므로 테스트는 실패합니다.
2️⃣ 기능 구현 단계
테스트를 통과시키기 위해 기능 코드를 작성합니다. 기능 코드는 최소한의 로직만 가지며, 테스트를 통과하는 것이 목표입니다.
3️⃣ 코드 개선 단계
테스트를 통과한 기능 코드를 개선하고, 코드의 가독성과 성능을 향상합니다.
🟠 TDD의 특징
1️⃣ 테스트 중심 개발
TDD는 기능 코드를 작성하기 전에 테스트를 먼저 작성하므로, 개발자는 기능이 어떻게 동작해야 하는지를 명확하게 인지하고 개발에 집중할 수 있습니다.
2️⃣ 안정적인 코드
테스트를 통과하지 못한 코드는 개발 과정에서 발견되므로 기능이 잘못 구현되는 것을 방지하고 안정적인 코드를 작성할 수 있습니다.
3️⃣ 코드의 재사용성
테스트 주도 개발은 작은 단위의 기능을 먼저 구현하므로 이후에 다른 기능에서 재사용할 수 있는 코드 조각이 많이 생성됩니다.
2️⃣ Gas 비용 측정
Hardhat은 스마트 컨트랙트의 함수 실행에 따른 Gas 비용 측정을 지원합니다. 이를 통해 함수가 얼마나 많은 Gas를 소비하는지 확인하고 최적화할 수 있는 정보를 얻을 수 있습니다.
3️⃣ 이더리움 네트워크 연결
Hardhat은 이더리움 네트워크와 연결할 수 있는 기능을 제공합니다. 이를 통해 로컬 개발 네트워크, 테스트넷, 메인넷 등 다양한 네트워크와 상호 작용하여 스마트 컨트랙트를 배포하고 테스트할 수 있습니다.
4️⃣ 계정 및 지갑 관리
Hardhat은 개발에 사용할 여러 이더리움 계정과 지갑을 관리하는 기능을 제공합니다. 개발자는 개인 키, 지갑 파일, HD Wallet 등을 사용하여 계정을 관리하고 테스트 및 배포에 사용할 수 있습니다.
💡 HD Wallet
HD Wallet은 계층적 지갑을 말합니다. HD Wallet은 암호화폐 지갑의 개인키를 계층적으로 생성하는 방식을 사용하여 다양한 암호화폐 계정을 관리하는 데 사용됩니다.
1️⃣ 단일 시드로 모든 개인키 생성
HD 지갑은 하나의 마스터 시드로부터 계층적으로 모든 개인키를 생성합니다. 이 시드는 일련의 단어로 구성된 멀티워드(mnemonic) 문구나 임의의 엔트로피(entropy)로 생성될 수 있습니다.
2️⃣ 계층 구조
HD 지갑은 계층 구조를 가지고 있습니다. 하나의 시드에서 파생된 하위 키들은 서로 계층적으로 연결되어 있으며, 각 계층은 일반적으로 숫자로 표현됩니다. 이렇게 구조화된 키 생성은 여러 개의 계정 또는 주소를 관리하고 백업하는 데 사용됩니다.
3️⃣ 중복 없는 키 생성
HD 지갑은 동일한 시드에서 중복 없이 개인키를 생성합니다. 이로 인해 여러 개의 주소를 생성하더라도 주소를 관리하고 백업하는데 유용합니다.
5️⃣ 플러그인 지원
Hardhat은 플러그인을 설치하여 기능을 확장하는 기능을 제공합니다. 사용자가 원하는 추가 기능을 간편하게 연결하고 사용할 수 있도록 설계되어 있습니다.
6️⃣ 이더리움 스마트 컨트랙트 언어 지원
Hardhat은 Solidity 뿐만 아니라 Vyper와 같은 다른 스마트 컨트랙트 언어도 지원합니다. 이를 통해 다양한 언어로 스마트 컨트랙트를 작성하고 테스트할 수 있습니다.
💡 Vyper
Vyper는 이더리움 블록체인을 위한 스마트 컨트랙트 개발 언어로, Python에 영감을 받아 디자인된 언어로서, 코드의 가독성과 이해하기 쉬운 문법을 강조합니다. 특히, Solidity보다 간결하고 단순한 문법을 가지고 있어서, 스마트 컨트랙트의 코딩을 더 쉽고 안전하게 만드는 데 도움을 줍니다.
👉 Hardhat Runner
Hardhat Runner는 Hardhat 프레임워크에서 제공하는 기능 중 하나로, 작업 및 플러그인 개념을 중심으로 설계되었습니다.
예를 들어, npx hardhat compile명령은 기본적으로 제공되는 compile 작업을 실행합니다. 이 작업은 Solidity 소스 코드를 컴파일하여 EVM에서 실행 가능한 바이트코드로 변환하는 역할을 합니다. Hardhat Runner는 이러한 작업들을 자동으로 처리하며, 사용자는 추가적으로 필요한 작업들을 등록하여 원하는 작업들을 실행할 수 있습니다.
💡 플러그인
플러그인은 기본 소프트웨어에 추가적인 기능을 제공하기 위해 설치하여 확장하는 소프트웨어 구성 요소입니다. 플러그인은 원래 소프트웨어의 기능을 개선하거나 새로운 기능을 추가할 수 있도록 설계되었습니다.
👷 Hardhat Runner 기능
❗️Hardhat 명령어 사용법
hardhat [GLOBAL OPTIONS] <TASK> [TASK OPTIONS]
🔴 GLOBAL OPTIONS
--config : Hardhat 설정 파일입니다.
--emoji : 메시지에 이모지를 사용합니다.
--help : 도움말을 표시합니다. 작업 이름을 제공하면 해당 작업의 도움말을 표시합니다.
--max-memory : Hardhat이 사용할 수 있는 최대 메모리 양입니다.
--network : 연결할 네트워크입니다.
--show-stack-traces : 스택 트레이스를 표시합니다.
💡 스택 트레이스
스택 트레이스는 프로그램이 실행되는 동안 함수 호출의 연속을 나타내는 추적 정보입니다. 일반적으로 오류 또는 예외가 발생했을 때 디버깅이나 오류 해결을 위해 사용됩니다. 스택 트레이스는 호출된 함수들의 위치와 상태를 기록하여 오류가 발생한 원인을 파악하는데 도움을 줍니다.
--tsconfig : TypeScript 설정 파일입니다.
--verbose : Hardhat의 자세한 로깅을 활성화합니다.
--version : Hardhat의 버전을 표시합니다.
🔴 TASK OPTIONS
check : 필요한 내용을 확인합니다.
clean : 캐시를 지우고 모든 아티팩트를 삭제합니다.
💡 아티팩트
아티팩트는 소스 코드를 컴파일하여 생성된 스마트 컨트랙트의 바이너리 코드와 관련된 정보를 포함하는 파일입니다. 스마트 컨트랙트 개발에서 아티팩트는 컴파일된 결과물을 의미하며, 보통 JSON 형식으로 저장됩니다.
💡 스마트 컨트랙트 아티팩트 정보
1️⃣ 바이너리 코드
스마트 컨트랙트의 기계어 형태인 바이너리 코드가 포함됩니다. 이 코드는 실제로 블록체인 네트워크에서 실행되는 코드이며, 컨트랙트의 동작을 정의합니다.
2️⃣ ABI (Application Binary Interface)
컨트랙트와 상호작용하기 위해 사용되는 인터페이스 정보가 포함됩니다. ABI는 함수 시그니처, 입력 매개변수, 출력 값 등을 포함하여 다른 스마트 컨트랙트나 외부 애플리케이션에서 컨트랙트와 상호작용할 수 있도록 합니다.
3️⃣ 소스 맵 (Source Map)
컨트랙트의 소스 코드와 바이너리 코드 간의 매핑 정보를 포함합니다. 이를 통해 컨트랙트의 바이너리 코드에서 발생한 오류를 원래 소스 코드의 위치로 역추적하는 데 사용됩니다.
4️⃣ 컨트랙트 메타데이터
컨트랙트의 이름, 버전, 컴파일러 정보 등과 같은 메타데이터가 포함될 수 있습니다.
compile : 프로젝트 전체를 컴파일하여 모든 아티팩트를 빌드합니다.
console : Hardhat 콘솔을 엽니다.
💡 Hardhat 콘솔
Hardhat 콘솔은 Hardhat 개발 환경 내에서 상호작용하고 스마트 컨트랙트를 테스트하며 디버깅할 수 있는 대화형 콘솔 환경입니다. 콘솔을 실행하면 Javascript 코드를 입력하여 스마트 컨트랙트와 상호 작용할 수 있으며, 이를 통해 스마트 컨트랙트의 함수를 호출하고 트랜잭션을 보내고 컨트랙트 상태를 확인할 수 있습니다.
coverage : 테스트에 대한 코드 커버리지 보고서를 생성합니다.
💡 코드 커버리지 보고서
코드 커버리지 보고서는 소프트웨어 테스트의 한 종류로, 소스 코드의 실행 가능한 부분과 실행되지 않은 부분을 평가하는 보고서입니다. 코드 커버리지는 소프트웨어의 테스트 케이스가 소스 코드의 얼마나 많은 부분을 실행하는지를 측정하는 데 사용됩니다.
💡 코드 커버리지 종류
🟠 라인 커버리지 (Line Coverage)
라인 커버리지는 테스트 케이스에 의해 실행된 소스 코드의 라인 수를 전체 소스 코드의 라인 수로 나눈 비율을 의미합니다. 이것은 코드 중 얼마나 많은 부분이 테스트되었는지를 보여주며, 테스트되지 않은 라인은 테스트가 필요한 코드로 간주됩니다. 라인 커버리지가 높을수록 테스트된 코드의 비율이 높아진다는 것을 의미하며, 이는 코드 품질을 나타내는 지표 중 하나입니다.
🟠 브랜치 커버리지 (Branch Coverage)
브랜치 커버리지는 조건문에서 각 분기 경로가 얼마나 실행되었는지를 측정하는 지표입니다. 이는 조건문의 참과 거짓 분기가 각각 얼마나 실행되었는지를 나타내며, 모든 분기가 테스트되었을 때 100%의 브랜치 커버리지가 달성됩니다. 브랜치 커버리지는 복잡한 조건문을 가진 코드에서 조건문의 모든 경우를 확인하는 데 도움 됩니다.
🟠 함수 커버리지 (Function Coverage)
함수 커버리지는 소스 코드의 함수 중 테스트 케이스에 의해 실행된 함수의 수를 전체 함수 수로 나눈 비율을 말합니다. 이것은 테스트되지 않은 함수를 찾는 데 도움이 되며, 테스트되지 않은 함수는 테스트 케이스에 의해 확인되지 않은 코드 경로를 나타낼 수 있습니다.
flatten : 컨트랙트와 해당 종속성을 펼쳐서 출력합니다.
help : 메시지를 출력합니다.
node : Hardhat Network 위에 JSON-RPC 서버를 시작합니다.
run : 프로젝트를 컴파일한 후 사용자가 정의한 스크립트를 실행합니다.
test : Mocha 테스트를 실행합니다.
typechain : 컴파일된 컨트랙트에 대한 Typechain 타입들을 생성합니다.
💡 Typechain
Typechain은 스마트 컨트랙트를 Typescript로 타입 정적 분석이 가능한 형태로 변환해 주는 도구입니다. 스마트 컨트랙트는 일반적으로 Solidity와 같은 언어로 작성되는데, 이러한 스마트 컨트랙트는 정적 타입이 없는 동적 언어로서, 컴파일 시에 오류를 잡기 어려울 수 있습니다.
Typechain은 Hardhat과 같은 Ethereum 개발 도구와 통합하여 사용되며, 컴파일된 스마트 컨트랙트 ABI를 기반으로 TypeScript 타입 선언 파일을 자동으로 생성합니다. 이렇게 생성된 타입 선언 파일은 개발자가 스마트 컨트랙트를 사용할 때 타입 안전성을 제공하고, IDE에서 자동 완성과 같은 기능을 사용할 수 있도록 도와줍니다.
💡 IDE
IDE는 통합 개발 환경(Integrated Development Environment)의 약자로, 소프트웨어 개발에 필요한 다양한 도구와 기능들이 통합되어 제공되는 개발 환경을 말합니다. 개발자가 소프트웨어를 개발하는 데 사용하는 모든 도구와 서비스를 하나의 통합된 인터페이스에서 사용할 수 있도록 도와줍니다.
verify : Etherscan에서 컨트랙트를 검증합니다.