내 “완벽한” 계약을 깨뜨린 테스트
Source: Dev.to
(번역할 텍스트를 제공해 주시면 한국어로 번역해 드리겠습니다.)
Why Dev Tools Matter More Than Ever
테스트가 처음으로 내 “완벽한” 스마트 계약을 파괴했을 때, 해커가 아니었다. 내 개발 환경 자체였다. 나는 AI‑지원 Solidity 계약을 막 끝냈는데—코드는 깔끔하고, 컴파일러 경고도 없으며, 몇 개의 정상 경로 테스트가 통과하고 있었다.
그런 다음 프레임워크를 바꾸고 한 번의 명령을 실행했을 때, 퍼즈 테스트가 그 계약을 산산조각 내는 모습을 지켜보았다. 같은 계약, 같은 로직, 다른 도구.
그때 깨달았다:
계약을 어떻게 개발하고 테스트하느냐(Hardhat, Foundry, 정적 분석기 등)는 무엇을 쓰느냐만큼이나 중요하다.
왜 개발 도구가 지금 중요한가
지금까지 이 시리즈에서 여러분은:
- 간단한 계약을 작성하고 배포했습니다.
- 재진입 같은 버그가 실제 돈을 빼앗을 수 있다는 것을 보았습니다.
- AI가 “작동하는” Solidity 코드를 생성하지만 여전히 보안 함정을 숨길 수 있다는 것을 목격했습니다.
현재 상황:
- 스마트 계약 공격으로 매년 수억 달러가 손실되고 있습니다.
- 보안 표준(예: OWASP 스마트 계약 Top 10, 감사 회사 가이드)은 테스트, 퍼징, 정적 분석을 요구합니다. 단순히 “컴파일 된다”는 수준이 아닙니다.
대부분의 진지한 팀은 다음을 혼합해서 사용합니다:
- 개발 프레임워크 – Hardhat / Foundry
- 자동화 테스트 – 단위, 통합, 퍼징
- 정적 분석 도구 – Slither, Aderyn
따라서 오늘날 Web3를 배우고 있다면, Solidity 문법만 배우는 것이 아니라 워크플로우를 배우는 것입니다.
Hardhat – 자바스크립트 사이드킥
Hardhat은 수년간 기본 이더리움 개발 도구였으며 여전히 많이 사용됩니다. 풀스택 개발 동반자라고 생각하세요:
- JavaScript 또는 TypeScript 로 테스트와 스크립트를 작성합니다.
- 계약을 배포하고, 메인넷을 포크하고, 작업을 실행하며, 프론트엔드 도구와 연결합니다.
- 방대한 플러그인 생태계(Ethers.js, OpenZeppelin, 가스 리포터, 커버리지 등).
초보자와 프로덕트 팀이 Hardhat을 사랑하는 이유
- Web2나 React 배경이라면 JS/TS 테스트가 자연스럽게 느껴집니다.
- MetaMask, Alchemy, Infura 같은 인프라와 잘 어울립니다.
- 로컬 테스트에서 메인넷 포크를 이용해 실제 사용자 흐름을 시뮬레이션할 수 있습니다.
약점
- 테스트는 JS/TS에, 계약은 Solidity에 존재해 컨텍스트 전환이 일부 사람들을 느리게 할 수 있습니다.
- 퍼징 및 고급 테스트는 보통 플러그인 기반이며 내장되어 있지 않습니다.
Hardhat이 빛을 발하는 경우
- 프론트엔드가 있는 dApp을 구축할 때.
- 풍부한 도구와 통합을 원할 때.
- “순수 Solidity”뿐 아니라 “프로덕트 흐름”도 생각할 때.
Foundry – Solidity‑네이티브 파워 툴
Foundry는 Solidity‑중심 작업과 보안‑지향 작업에서 빠르게 사랑받는 도구가 되었습니다. 고성능 테스트 및 보안 장비라고 생각하면 됩니다:
- 테스트를 직접 Solidity 로 작성합니다.
forge test로 실행합니다.- 내장된 퍼징, 인버리언트 테스트, 치트코드, 그리고 번개처럼 빠른 컴파일 시간.
주요 장점
| Feature | Benefit |
|---|---|
| Speed | 벤치마크에 따르면 Foundry는 기존 JS‑기반 환경보다 여러 배 빠르게 컴파일하고 테스트를 실행합니다. |
| Solidity‑first | JS/TS 레이어가 없으며, 테스트가 곧 계약입니다. 하나의 언어에 머물면서 EVM처럼 사고할 수 있습니다. |
| Security‑friendly | 퍼징과 인버리언트가 일급 기능으로 제공되어, 최신 보안 가이드가 권장하는 바로 그 방식입니다. |
이전 글들과 연결되는 이유
- AI‑생성 계약을 검토할 때, 퍼징 테스트는 생각조차 못한 이상한 입력을 잡아낼 수 있습니다.
- 재진입 공격이나 논리 버그가 걱정될 때, 인버리언트를 사용해 “총 잔액은 입력에 관계없이 절대 음수가 되지 않는다”와 같은 조건을 검증할 수 있습니다.
Foundry가 빛을 발하는 경우
- Solidity 정확성과 보안을 깊이 있게 신경 쓸 때.
- 대부분 Solidity 안에서 작업하는 것이 편할 때.
- 테스트와 계약을 빠르게 반복하고 싶을 때.
Source: …
So… Hardhat or Foundry?
대부분의 빌더에게 솔직한 답은 종종: 둘 다, 작업에 따라 다릅니다.
Mental model
| Tool | Focus |
|---|---|
| Hardhat | Product & integration – JS/TS tests, mainnet forking, plugin ecosystem, frontend/devops integrations. |
| Foundry | Solidity & security – Fast compile/test loop, Solidity‑only tests, built‑in fuzzing & invariants. |
당신은 하나의 툴에 영원히 얽매일 필요가 없습니다. 일반적인 워크플로우:
- Prototype & core‑logic testing with Foundry.
- Deployment scripts, mainnet forks, and frontend integration with Hardhat.
For this 60‑day journey
- Solidity에 익숙해지고 싶다면, Foundry 테스트부터 시작하는 것이 실제로 Solidity를 더 빠르게 배울 수 있게 해줍니다.
- JS/TS에 더 익숙하다면, Hardhat은 스마트 계약으로 부드럽게 진입할 수 있는 경로입니다.
진짜 실수는 “잘못된” 프레임워크를 고르는 것이 아니라,
프레임워크를 전혀 진지하게 사용하지 않고 Remix + 희망에만 의존하는 것입니다.
Slither와 Aderyn이 적용되는 경우
지난 기사에서, 미디엄 팔로워 MihaiHng이 다음과 같이 댓글을 달았습니다:
“수동 검토로 CEI 패턴이 지켜지는지 확인하는 것 외에도, Slither와 Aderyn 같은 매우 유용한 정적 분석 도구들이 있습니다.”
그는 전적으로 옳습니다. 수동 검토 + CEI는 중요하지만, 현대 보안 문화는 당신이 놓칠 수 있다는 가정에 기반합니다. 바로 정적 분석기가 필요한 이유입니다.
Slither (Trail of Bits)
- 가장 널리 사용되는 Solidity 정적 분석 도구 중 하나입니다.
- 재진입, 접근 제어 문제, 위험한 패턴 등 일반적인 취약점을 빠르게 탐지합니다.
- CI에 잘 통합되며 Hardhat과 Foundry 프로젝트 모두에서 작동합니다.
Aderyn (Cyfrin)
- Solidity 프로젝트에 초점을 맞춘 최신 정적 분석기입니다.
- Foundry와 Hardhat 레이아웃을 일류 수준으로 지원합니다.
- JSON/Markdown/SARIF 형식으로 보고서를 생성하고 VS Code에 플러그인되어 에디터 내 피드백을 제공합니다.
현실적인 워크플로우
- Hardhat 또는 Foundry에서 테스트를 작성합니다.
- 퍼징/인베리언트를 실행해 더 깊은 커버리지를 확보합니다.
- 또한 Slither/Aderyn을 실행해 사람이나 테스트가 놓칠 수 있는 패턴을 잡아냅니다.
복사할 수 있는 개발 워크플로우
Here’s a lightweight process you can actually run on your next contract:
1. 프로토타입
- AI를 (신중히) 사용하고 직접 편집하여 Solidity 코드를 초안합니다.
- 계약을 작고 집중된 형태로 유지합니다.
2. 프레임워크 선택
-
JS 환경이라면:
npx hardhat init # write JS/TS tests -
Solidity‑우선이라면:
forge init # write Solidity tests
3. 테스트 작성
- 정상 흐름을 위한 단위 테스트.
- 엣지 케이스를 위한 퍼징 테스트 / 불변 조건 테스트.
4. 정적 분석 실행
# Hardhat example
npx hardhat run scripts/deploy.ts
slither .
# Foundry example
forge test
aderyn .
5. CI 통합
forge test && slither .또는hardhat test && slither .를 실행하는 GitHub Actions 워크플로를 추가합니다.- 발견 사항이 있으면 빌드를 실패 처리합니다.
6. 배포
- 프론트엔드에 바로 사용할 수 있는 배포를 위해 Hardhat 스크립트를 사용하거나, 빠른 메인넷 포크를 위해 Foundry의
forge create를 사용합니다.
Solidity land: Foundry 프로젝트, Solidity 테스트
기본 테스트 작성
- Happy‑path 단위 테스트 – 입금, 출금, 상태 변화.
- 몇 가지 “성가신 사용자” 케이스 (0값, 큰 값, 반복 호출).
퍼징 / 불변식 추가
- Foundry – 내장 퍼징 테스트와 불변식 사용.
- Hardhat – 필요하면 플러그인이나 외부 도구로 퍼징 추가.
정적 분석 실행
- Slither – 알려진 버그 패턴에 대한 빠른 스캔.
- Aderyn – 추가 탐지기와 최신 스택과의 더 나은 통합.
테스트넷 / 메인넷은 그 다음에 생각하기
테스트 + 퍼징 + 정적 분석이 모두 통과되면 테스트넷(예: Sepolia)에 배포합니다.
- 커뮤니티와 주소를 공유하여 더 많은 눈으로 검증받으세요.
TL;DR
- Hardhat = 제품 중심, JS/TS 친화적, 풍부한 플러그인 생태계.
- Foundry = Solidity 중심, 초고속, 보안 우선.
- Slither & Aderyn = 정적 분석 안전망.
작업에 맞게 조합해서 사용하고, 절대 하나의 도구에만 의존하지 마세요. 즐거운 개발 되세요!
다음에 올 내용
오늘의 글은 전체적인 시각으로 다음과 같은 질문을 던졌습니다:
“실제 팀들은 스마트 계약을 어떻게 개발하고 테스트할까요?”
내일은 다시 세부적으로 들어가 실제 계약을 가지고 전체 과정을 직접 진행해 보겠습니다:
- 작은 AI‑생성 Solidity 계약을 가져옵니다.
- 이를 Foundry 프로젝트에 포함시킵니다.
- 몇 개의 테스트를 추가하고, 퍼징과 인버리언트를 작성합니다.
- Slither 또는 Aderyn을 한 번 실행해 보고, 테스트넷에 배포하기 전에 어떤 문제를 잡아내는지 확인합니다.
오늘은 영토의 지도를 보는 단계라고 생각하세요.
내일은 그 지도를 따라 한 걸음씩 함께 걸어가며 전체 경로를 체험해 보겠습니다.
더 깊이 파고들기 위한 자료
- Solidity Docs — Security Considerations – 외부 호출이 위험한 이유와 상태 변화를 안전하게 구조화하는 방법을 설명하는 공식 언어 문서.
- ConsenSys Diligence — Smart Contract Best Practices – 공격 패턴, 체크‑이펙트‑인터랙션, 일반적인 함정에 대한 고전적인 참고 자료.
- OpenZeppelin Contracts — ReentrancyGuard – 재진입 잠금의 사실상 표준 구현; 패턴을 실제로 사용하는 방법을 이해하는 데 완벽함.
- Foundry Documentation – 설치, 퍼징 테스트, 인버리언트, 치트코드 등에 대한 완전 가이드.
시리즈를 팔로우하세요
- Medium: Ribhav Modi
- Twitter: @RibsModi
- Future: Ribhav Modi
텔레그램에서 대화에 참여하세요: Web3ForHumans 그리고 함께 만들어갑시다.