💡 핵심 인사이트
스마트 컨트랙트는 한 번 블록체인에 배포되면 영원히 코드를 수정(패치)할 수 없으며, 내부의 모든 로직이 해커에게 100% 투명하게 공개됩니다.
따라서 코딩 실수 한 줄이 곧바로 수천억 원의 코인 탈취로 이어집니다. 대표적인 해킹 기법이 **재진입 공격(Re-entrancy)**과 **오버플로우(Overflow)**입니다.


Ⅰ. 스마트 컨트랙트가 해킹에 취약한 근본적 이유

기존 웹 서버(은행 앱)는 해커가 공격해 오면 즉시 서버를 끄고 소스 코드를 패치하면 됩니다. 소스 코드 자체도 꽁꽁 숨겨져 있습니다.

하지만 이더리움 스마트 컨트랙트는 코드가 퍼블릭하게 만천하에 공개되어 해커가 여유롭게 취약점을 연구할 수 있습니다. 결정적으로, 탈중앙화의 원칙("코드가 곧 법이다") 때문에 한 번 올라간 코드는 창시자조차 지우거나 덮어쓸 수 없습니다. (업그레이드 가능한 프록시 컨트랙트 우회법이 있긴 하나 기본적으로 불변성(Immutability)을 가집니다). 따라서 배포 전 극단적으로 철저한 코드 감사(Audit)가 필수입니다.


Ⅱ. 치명적인 3대 보안 취약점

1. 재진입 공격 (Re-entrancy Attack) ★가장 유명함

  • 사건: 2016년 이더리움 메인넷을 두 갈래(이더리움과 이더리움 클래식)로 쪼개버린 전설적인 **'The DAO 해킹 사건'**의 원인입니다.
  • 원리: 코인의 출금(Withdraw) 로직의 순서 결함을 노린 해킹입니다.
    1. 은행(컨트랙트)이 사용자에게 100만 원을 보내줍니다.
    2. 그 직후, 은행의 장부(잔고 변수)에서 사용자의 잔고를 0원으로 차감(업데이트)해야 합니다.
    3. 해커는 악의적인 컨트랙트를 만들어, 1번(돈 받음)과 2번(장부 깎임)의 찰나의 틈 사이에 멈추지 않고 계속해서 "돈 더 내놔!"라는 재진입 함수를 재귀적으로 무한 호출합니다.
    4. 은행 장부는 아직 잔고가 0으로 깎이지 않았으므로 바보처럼 계속 돈을 내어주고, 결국 은행 금고가 텅 빌 때까지 무한 출금이 발생합니다.
  • 해결책: "장부(상태 변수)부터 먼저 0으로 깎아놓고(Checks-Effects), 그다음에 외부로 돈을 송금하라(Interactions)"는 CEI 패턴을 엄수해야 합니다.

2. 정수 오버플로우/언더플로우 (Integer Overflow/Underflow)

  • 원리: 구형 솔리디티(Solidity 0.8 이전 버전)에서 변수가 담을 수 있는 숫자의 한계(예: 0~255)를 악용합니다.
  • 지갑 잔고가 0원인 상태에서 해커가 누군가에게 1원을 몰래 송금(빼기)하면, 잔고가 마이너스(-1)가 되는 게 아니라 미터기가 한 바퀴 돌아 최댓값인 **255원(혹은 2^256-1이라는 무한대에 가까운 돈)**으로 조작되어 버리는 현상입니다.
  • 해결책: 현재는 솔리디티 컴파일러가 알아서 에러를 내어 막아주거나, SafeMath 같은 라이브러리를 써서 덧셈/뺄셈을 방어합니다.

3. 프론트 러닝 (Front-Running)

  • 원리: 블록체인은 거래가 확정(블록에 담김)되기 전, 멤풀(Mempool)이라는 대기실에 잠시 머뭅니다. 누구나 이 대기실을 훔쳐볼 수 있습니다.
  • 일반 유저가 "A 코인을 1억 원어치 살게!"라는 주문을 멤풀에 올립니다. 해커(채굴자 봇)가 이 주문을 보고 "오, 코인 값 오르겠네?"라며 수수료(가스비)를 엄청나게 비싸게 지불하여 자신의 매수 주문을 새치기(Front-running)해서 블록에 먼저 담아버립니다. 해커가 싸게 사서 비싸게 파는 무위험 차익을 거둡니다.

📢 섹션 요약 비유: 재진입 공격은 ATM기가 돈을 뱉어내고 내 통장 잔고를 깎으려는 찰나, 기계가 영수증을 인쇄하는 1초의 틈을 타서 취소 버튼을 무한 광클하여 내 통장 잔고는 안 깎이고 돈만 계속 토해내게 만드는 악마의 해킹 버그입니다.