OpenZeppelin contracts-upgradeable로 UUPS·Transparent 프록시 배포와 업그레이드 가이드

개요 OpenZeppelin의 contracts-upgradeable은 업그레이드 가능한 스마트 컨트랙트를 안전하게 구현하기 위한 베이스 라이브러리 프록시 Proxy 패턴으로 사용자 호출 주소와 로직 컨트랙트를 분리하고 delegatecall로 로직을 실행 Transparent Proxy와 UUPS 두 방식을 공식 지원 이 글은 Hardhat 환경에서 @openzeppelin/hardhat-upgrades 플러그인과 함께 UUPS를 중심으로 배포와 업그레이드 흐름을 정리하고, Transparent와의 차이점을 요약 핵심 개념 Proxy 컨트랙트와 Implementation 컨트랙트를 분리하여 배포 사용자는 Proxy 주소로 상호작용, Proxy는 delegatecall로 Implementation의 로직 실행 업그레이드는 Proxy가 가리키는 Implementation 주소를 교체하는 방식 EIP-1967 표준 슬롯을 사용해 Implementation 주소 보관 방식 요약 ...

February 22, 2026

CEI 패턴 Checks-Effects-Interactions로 재진입 방어

개념/배경 CEI 패턴은 Checks-Effects-Interactions의 약자 스마트 컨트랙트 함수에서 실행 순서를 명확히 해 재진입 공격을 줄이는 코드 규칙 핵심은 검증 후 상태 변경을 먼저 완료하고, 외부 호출을 마지막에 수행하는 흐름 유지 3단계 순서 1. Checks (검증) ↓ 2. Effects (상태 변경) ↓ 3. Interactions (외부 호출)이 순서를 지키면 외부로 제어권이 나가기 전에 내부 상태가 이미 안전하게 반영됨 재진입 시도는 변경된 상태에 의해 자연스럽게 차단됨 예시로 이해하기 잘못된 순서 위험 function withdraw(uint256 amount) external { // 1. Checks require(balances[msg.sender] >= amount); // 2. Interactions ← 너무 빠름 (bool success, ) = msg.sender.call{value: amount}(""); require(success); // 3. Effects ← 너무 늦음 balances[msg.sender] -= amount; }문제점 ...

January 17, 2026