스마트 계약
IT 위키
더 많은 작업
- Smart Contract; 스마트 컨트랙트
- 블록체인에 올려 두고 정해진 조건이 충족되면 사람의 개입 없이 자동으로 계약 내용을 실행하는 프로그램
- 특정 계약을 스스로 수립, 검증, 이행하기 위한 프로토콜
- 블록체인에서 동작하는 응용프로그램의 단위(EVM 바이트코드)
스마트 계약이라는 개념은 1994년 닉 재보(Nick Szabo)가 제안했고, 2015년 이더리움이 튜링 완전한 실행 환경인 EVM을 제공하면서 본격적으로 쓰이기 시작했다. 개발자는 주로 솔리디티(Solidity) 같은 언어로 계약 코드를 작성해 컴파일한 바이트코드를 블록체인에 배포한다. 배포된 계약은 고유 주소를 가지며, 누구나 거래(트랜잭션)를 보내 함수를 호출할 수 있고, 모든 노드가 같은 코드를 실행해 결과에 합의한다. 실행에는 연산량에 비례한 수수료(가스)가 든다.
탈중앙화 금융(DeFi), 토큰 발행(ERC-20), NFT(ERC-721), 탈중앙화 거래소, 보험금 자동 지급, 공급망 추적 등에 쓰인다.
- 자동 실행 : 조건이 맞으면 중개자 없이 코드대로 실행된다.
- 투명성 : 코드와 실행 기록이 공개되어 누구나 검증할 수 있다.
- 불변성 : 배포 후 코드를 고칠 수 없다. 장점이자 가장 큰 보안 약점이다.
- 자산 직접 보관 : 계약 자체가 암호화폐를 보유하고 이체한다. 버그가 곧 금전 손실이다.
- 외부 데이터 한계 : 블록체인 밖의 정보(시세, 날씨)는 오라클이라는 외부 데이터 공급자를 거쳐야 한다.
배포 후 수정이 어렵고 코드가 공개되어 있어, 공격자가 취약점을 찾아 자금을 즉시 빼낼 수 있다.
| 취약점 | 내용 | 사례·대책 |
|---|---|---|
| 재진입(Reentrancy) | 외부 계약에 송금할 때 상대 계약이 콜백으로 출금 함수를 다시 호출해, 잔액이 갱신되기 전에 반복 인출 | 2016년 The DAO 사건(약 360만 ETH 탈취, 이더리움 하드포크로 이어짐). 상태 변경 후 외부 호출(Checks-Effects-Interactions), 재진입 잠금 |
| 정수 오버플로·언더플로 | 산술 연산이 자료형 범위를 넘어 값이 뒤바뀜 | 2018년 BEC 토큰 사건. 솔리디티 0.8 이상의 기본 검사, SafeMath 라이브러리 |
| 접근 제어 미흡 | 소유자 전용 함수(초기화, 출금, 파기)에 권한 검사가 없거나 잘못됨 | 2017년 패리티 다중서명 지갑 사건. 권한 수정자, 역할 기반 접근 제어 |
tx.origin 인증 |
최초 호출자를 기준으로 인증해 중간 계약을 통한 피싱에 당함 | msg.sender로 인증
|
| 외부 호출 반환값 미확인 | 저수준 호출 실패를 무시하고 진행 | 반환값 검사, 안전한 송금 방식 |
| 프런트러닝 | 공개 대기 중인 거래를 보고 더 높은 수수료로 먼저 실행 | 커밋-공개(commit-reveal) 방식, 슬리피지 제한 |
| 오라클 조작 | 유동성이 작은 거래소 가격을 순간적으로 조작(플래시 론 이용)해 담보 가치를 속임 | 여러 출처의 시간 가중 평균 가격, 탈중앙 오라클 |
| 타임스탬프·난수 의존 | 블록 생성자가 어느 정도 조작할 수 있는 값을 난수나 조건에 씀 | 검증 가능한 난수 함수(VRF) |
| 서비스 거부 | 반복문이 가스 한도를 넘거나, 송금 실패로 전체 처리가 멈춤 | 반복 범위 제한, 받는 쪽이 직접 출금하는 pull 방식 |
| 업그레이드 구조 결함 | 프록시 패턴의 저장소 충돌, 초기화 함수 노출 | 검증된 프록시 라이브러리, 초기화 잠금 |
- Smart Contract Audit
- 스마트 계약을 배포하기 전에 코드의 보안 취약점, 논리 오류, 설계 의도와의 불일치를 전문가와 도구로 체계적으로 검사하는 활동
- 배포 후에는 코드를 고칠 수 없어 사전 검증만이 사실상 유일한 방어다.
- 계약이 직접 자산을 보관하므로 버그 하나가 수천억 원 손실로 이어진다.
- 코드가 공개되어 공격자도 같은 코드를 분석한다.
- 투자자·거래소가 상장이나 투자 전에 감사 보고서를 요구한다.
- 범위·요구사항 정의 : 감사 대상 계약과 버전(커밋), 백서·설계 문서, 의도한 동작과 권한 구조를 확정한다.
- 자동화 분석 : 정적 분석 도구(Slither 등)로 알려진 취약 패턴을 찾고, 심볼릭 실행 도구(Mythril 등)로 위험한 실행 경로를 탐색하며, 퍼징(Echidna, Foundry 등)으로 불변 조건이 깨지는지 시험한다.
- 수동 코드 리뷰 : 감사인이 코드를 한 줄씩 읽어 업무 논리 오류, 경제적 공격 가능성, 권한 설계 결함처럼 도구가 못 찾는 문제를 찾는다. 가장 중요한 단계다.
- 형식 검증(선택) : 핵심 성질(총 공급량 불변, 잔액 음수 불가)을 수학적으로 명세하고 모든 경우에 성립함을 증명한다.
- 테스트·시뮬레이션 : 테스트넷이나 메인넷 복제 환경에서 공격 시나리오를 재현한다.
- 보고서 작성 : 발견 사항을 심각도(치명·높음·중간·낮음·정보)로 분류하고 재현 방법과 수정 권고를 적는다.
- 수정 확인(재감사) : 개발팀이 고친 코드를 다시 검토해 조치 여부와 새 문제 발생 여부를 확인한다.
- 배포 후 관리 : 실시간 모니터링, 버그 바운티, 긴급 정지(pause) 기능과 사고 대응 계획을 운영한다.
| 기법 | 장점 | 한계 |
|---|---|---|
| 정적 분석 | 빠르고 넓게 알려진 패턴 탐지 | 오탐이 많고 업무 논리 오류는 못 찾음 |
| 심볼릭 실행 | 특정 상태에 도달하는 입력을 자동으로 찾음 | 경로 폭발로 큰 계약에 한계 |
| 퍼징 | 예상 못 한 입력과 호출 순서에서 불변 조건 위반 발견 | 불변 조건을 잘 정의해야 효과 |
| 수동 리뷰 | 설계·경제 모델 결함까지 발견 | 감사인 역량에 의존, 시간·비용 |
| 형식 검증 | 명세한 성질은 모든 입력에 대해 보장 | 명세 작성이 어렵고 명세 밖의 결함은 못 막음 |
감사는 알려진 범위에서 위험을 줄일 뿐 무결함을 보증하지 않는다. 감사를 받은 계약도 해킹된 사례가 많아, 감사 후에도 보안 코딩, 다중 감사, 단계적 배포, 모니터링을 함께 쓴다.
- 검사 → 상태 변경 → 외부 호출 순서(Checks-Effects-Interactions)를 지킨다.
- 검증된 공개 라이브러리(OpenZeppelin 등)를 쓰고 직접 구현을 줄인다.
- 함수마다 접근 권한을 명시하고 관리자 권한은 다중서명·시간 지연(timelock)으로 묶는다.
- 송금은 받는 쪽이 직접 꺼내 가는 pull 방식으로 한다.
- 긴급 정지 기능과 출금 한도를 둔다.
- 알려진 취약점 분류(SWC Registry, OWASP Smart Contract Top 10)를 점검표로 쓴다.