이더리움의 탄생은 한번 블록체인에 배포된 소스 코드가 영원히 존재하며 변경할 수 없다는 불변성의 원칙에 기반한 새로운 컴퓨팅 모델을 확립했습니다. 그러나 소프트웨어 개발 현실에서 이러한 불변성은 버그 수정, 기능 업데이트 및 시스템 최적화에 큰 장벽을 만듭니다. 블록체인의 불변성과 소프트웨어 유연성의 필요성 사이의 충돌을 해결하기 위해 프록시 계약 모델이 표준 솔루션으로 개발되었습니다. Tan Phat Digital 팀이 편집한 이 보고서는 프록시 계약의 성격, 기본 기술 메커니즘, 널리 사용되는 표준, 특히 실제 시나리오에서 최종 사용자를 쉽게 속이게 만드는 정교한 보안 위험을 심층 분석합니다.
1. 핵심 개념 및 상태와 로직의 분리
이더리움의 전통적인 스마트 계약은 실행 코드(로직)와 저장 공간(스토리지)이 단일 주소에 묶여 있는 모놀리식 개체입니다. 프록시 계약은 시스템을 두 개의 독립적이지만 밀접하게 상호 작용하는 구성 요소인 프록시 계약(상태 보유)과 논리 계약(실행 코드 보유)으로 분리하여 이 구조를 나눕니다.
이 모델을 사용하면 사용자 및 프런트엔드 애플리케이션에 대한 고정 주소를 유지할 수 있으며, 기본 비즈니스 로직은 프록시 메모리 내부의 논리 계약을 가리키는 주소를 변경하여 교체할 수 있습니다. 이는 본질적으로 불변인 인프라에 "가변성의 환상"을 만듭니다.
1.1 프록시 아키텍처에서 구성 요소의 역할
이 아키텍처에서 프록시 계약은 단일 연락 창구 역할을 합니다. 모든 자산, Ether 잔액, 소유권 및 사용자 잔액과 같은 중요한 상태 변수는 프록시 주소에 영구적으로 저장됩니다. 이와 대조적으로 논리 계약(구현 계약이라고도 함)에는 데이터 처리 방법에 대한 지침만 포함되어 있습니다.
주요 구성 요소는 다음과 같습니다.
프록시 계약: 데이터 저장소, 토큰 잔액, 구현 주소 및 관리 권한. 변경할 수 없는 주소 속성이 있지만 내부 데이터를 변경할 수 있습니다.
로직(구현): 비즈니스 기능(예: 전송, 발행, 스왑)의 소스 코드를 포함합니다. 새 버전으로 교체 가능.
ProxyAdmin: 관리 계약 또는 지갑에는 업그레이드를 수행할 권한이 있어 전체 시스템 변경 기능을 제어하는 데 도움이 됩니다.
이러한 분리는 시스템 유지 관리에 큰 이점을 제공합니다. 비즈니스 논리에서 보안 취약점이 발견되면 개발자는 수천 명의 사용자에게 자산을 완전히 새로운 주소로 이동하도록 요청할 필요 없이 단순히 새로운 고정 논리 계약을 배포하고 프록시의 주소를 업데이트합니다.
참조: 스마트 계약이란 무엇입니까?
2. DELEGATECALL 메커니즘: 업그레이드의 엔진
프록시 계약이 작동할 수 있도록 하는 기술적 기반은 이더리움 네트워크의 EIP-7에 도입된 opcode delegatecall입니다. 이는 계약이 다른 주소에서 실행 가능한 코드를 가져오지만 자체 "컨텍스트"에서 실행되도록 허용하는 특수 호출입니다.
2.1 EVM 실행에서 컨텍스트 유지
프록시 계약이 로직 계약에 delegatecall을 생성하면 트랜잭션의 환경 변수가 그대로 유지됩니다. 이는 로직 계약 내에서 프록시를 직접 호출하는 것과 비교하여 다음 값이 변경되지 않음을 의미합니다.
msg.sender: 여전히 프록시 주소가 아닌 원래 사용자의 주소입니다.msg.value: 트랜잭션에 포함된 Ether의 양이 유지됩니다. 리소스.저장: 모든 읽기(SLOAD) 및 쓰기(SSTORE)는 논리 계약이 아닌 프록시의 저장 공간에서 직접 작동합니다.
일반 호출(CALL)과 DELEGATECALL의 차이점은 보안과 기능에 매우 중요합니다. 시스템 능력. CALL 명령에서 대상 계약은 자체 메모리에서 작동하며 msg.sender를 호출 계약으로 간주합니다. DELEGATECALL에서 대상 계약은 프록시 서버에 로드된 논리 라이브러리 역할을 합니다.
2.2 Fallback 기능을 통한 실행 흐름 분석
프록시 계약은 일반적으로 충돌을 피하기 위한 비즈니스 기능을 정의하지 않으므로 알 수 없는 호출을 수신하기 위해 fallback 기능을 사용합니다. 사용자가 프록시에서 transfer(address,uint256) 함수를 호출하면 프록시에는 이 함수가 없으므로 Ethereum 가상 머신(EVM)이 fallback 함수를 트리거합니다. 여기서 호출을 승인하기 위해 하위 수준 어셈블리 코드가 실행됩니다.
기술 프로세스는 다음과 같습니다:
calldatacopy를 사용하여 트랜잭션의 전체 입력 데이터를 메모리에 복사합니다.지정된 저장 위치에서 현재 논리 계약의 주소를 가져옵니다.
명령을 실행합니다. 사용 가능한 모든 가스가 포함된
delegatecall은 복사된 데이터를 전달합니다.Logic 계약 실행이 완료된 후 결과가 반환되고 출력 데이터는
returndatacopy를 사용하여 다시 복사됩니다.프록시는 결과를 원래 사용자에게 반환하여 위임 주기를 투명하게 완료합니다.
3. 메모리 아키텍처 및 EIP-1967 표준
프록시 패턴의 가장 큰 과제 중 하나는 메모리 충돌(Storage Collision)을 관리하는 것입니다. 프록시와 구현 모두 동일한 프록시의 저장 공간을 공유하므로 서로 다른 목적으로 동일한 메모리 "슬롯"을 사용하려고 하면 재앙이 발생합니다.
3.1 메모리 충돌 위험
Solidity에서 상태 변수는 선언 순서에 따라 32바이트 슬롯으로 정렬됩니다. 프록시가 논리 주소를 저장하기 위해 슬롯 0에 변수 address _implementation를 선언한다고 가정합니다. 논리 계약이 슬롯 0에도 변수 uint256 _balance를 선언하면 논리 함수가 잔액을 업데이트할 때마다 실수로 프록시의 자체 주소를 덮어쓰게 됩니다. 이는 공격자가 해당 슬롯에 기록된 값을 조작할 수 있는 경우 계약을 탈취하게 됩니다.
3.2 구조화되지 않은 저장소 및 EIP-1967 솔루션
충돌을 방지하기 위해 식별자 문자열을 해싱하여 프록시 관리 변수에 대한 특수 저장소 위치를 정의하는 EIP-1967 표준이 확립되었습니다.

해싱 후 1을 빼면 Solidity에서 동적 배열 또는 매핑의 일반적인 해싱으로 이 슬롯을 생성할 수 없도록 하여 갑자기 충돌 가능성이 최소화됩니다. 거의 0입니다.
자세히 보기: 스마트 계약 감사란 무엇입니까?
4. 인기 있는 프록시 모델 및 절충 분석
4.1 투명 프록시 패턴(TPP)
이 모델은 "기능 식별자 충돌" 문제를 해결하는 것을 목표로 합니다. TPP의 메커니즘은 호출자 분산화를 기반으로 합니다. 호출자가 관리자인 경우 프록시는 자체 관리 기능만 호출합니다. 호출자가 관리자가 아닌 경우 프록시는 항상 호출을 구현으로 전달합니다.
4.2 UUPS(Universal Upgradeable Proxy Standard) - EIP-1822
UUPS는 업그레이드 논리를 프록시에서 구현 계약 자체로 이동하여 TPP보다 성능이 뛰어납니다. 이제 프록시가 매우 간소화되어 프록시에서 관리자를 확인할 필요가 없기 때문에 가스를 절약하는 데 도움이 됩니다. 그러나 업그레이드 논리가 없는 새 버전으로 업그레이드하면 계약이 영원히 잠깁니다.
4.3 비콘 프록시
동일한 계약을 일련으로 배포해야 하는 프로젝트를 위해 설계되었습니다. 프록시는 공통 구현 주소를 보유하는 "Beacon"이라는 중간 계약을 가리킵니다. 비콘이 업데이트되면 모든 종속 프록시가 동시에 업그레이드됩니다.
4.4 Diamond Standard(EIP-2535)
Diamond Standard를 사용하면 하나의 프록시 계약을 다양한 구현 계약(Facets)에 연결할 수 있습니다. 이는 로직을 분할하고 각 부분을 독립적으로 업그레이드할 수 있도록 하여 24KB 계약 크기 제한을 해결합니다.
5. 보안 위험 및 사용자 사기 메커니즘
Tan Phat Digital의 관찰에 따르면 사용자는 블록 탐색기에서 변경되지 않은 계약 주소나 확인된 소스 코드를 볼 때 잘못된 보안 감각에 속는 경우가 많습니다.
5.1 관리 및 중앙화의 위험
가장 큰 위험은 관리자의 절대적인 통제입니다. 관리자 키가 손상된 경우 공격자는 악성 소스 코드에 "플래시 업그레이드"를 수행하여 자금을 인출한 다음 이전 버전으로 다시 업그레이드하여 흔적을 지울 수 있습니다.
5.2 초기화 오류(초기화되지 않은 프록시 취약점)
프록시는 생성자를 사용할 수 없으므로 개발자는 초기화 기능을 사용합니다. 관리자가 이 함수 호출을 잊어버리거나 보호하지 않으면 공격자가 직접 호출하여 관리자 권한을 탈취할 수 있습니다. 500,000 ETH 이상을 동결시킨 2017년 Parity 지갑 해킹은 이 버그의 고통스러운 역사적 예입니다.
5.3 메모리 충돌 및 Audius 충돌
2022 Audius 프로토콜 해킹은 메모리 슬롯 오류의 예입니다.
업그레이드 전: 슬롯 0은 초기 상태 생성을 저장합니다. (
초기화됨 = true). 계약은 정상적으로 작동합니다.업그레이드 후: 개발자가 프록시에
proxyAdmin변수를 추가했는데 실수로 슬롯 0이 겹쳤습니다.Exploit: 관리자의 주소 값으로 인해 시스템이 초기화되지 않은 것으로 오해하게 됩니다. 해커는
initialize함수를 다시 호출하고 소유권을 가져옵니다.피해: 해커는 커뮤니티 기금에서 600만 달러 상당의 토큰을 이체합니다.
5.4 은폐 및 변장 기술
사기꾼은 종종 safeWithdraw()와 같은 위험한 함수를 언급하지만 실제로는 자금을 빼내는 기능입니다. 또한 악성 "백도어"가 포함된 구현 소스 코드를 숨기는 동안 프록시의 소스 코드(매우 짧고 무해함)만 확인할 수 있습니다.
6. 일반적인 러그 풀 프록시 사례 분석(2024~2025년)
6.1 LIBRA 케이스 및 러그 풀 진화
2025년 LIBRA 프로젝트는 탐지를 피하기 위해 "조각난 러그 풀" 전략을 사용했습니다. 한 번의 대규모 인출 대신 사기꾼은 프록시를 사용하여 인출을 일련의 위성 지갑에 배포하고 모니터링 시스템의 경고 임계값 미만으로 수천 건의 소규모 거래를 수행합니다. 그런 다음 증거를 없애기 위해 selfdestruct 명령이 포함된 계약으로 프록시를 업그레이드했습니다.
6.2 Kinto Finance 및 저수준 프록시 취약점
2025년 7월, Kinto Finance는 프록시 관리 메커니즘의 버그를 통해 공격을 받았습니다. 공격자는 업그레이드 권한을 장악하고 신속하게 110,000개의 승인되지 않은 토큰을 추가로 발행하여 유동성 풀에서 155만 달러를 인출했습니다.
7. 사용자를 위한 테스트 및 확인 프로세스
자산을 보호하기 위해 Tan Phat Digital은 사용자가 다음 단계를 수행할 것을 권장합니다.
프록시 확인 기능 확인: Etherscan에 "프록시로 읽기" 탭이 표시되는지 확인하세요.
업그레이드 내역 모니터링: 계약이 예고 없이 너무 자주 업그레이드되면 위험 신호입니다. 위험합니다.
관리자 권한 확인: 관리자 주소는 다중 서명 지갑(Multisig)이어야 하거나 중요한 변경을 지연시키기 위한 Timelock 메커니즘이 있어야 합니다.
지원 도구 사용: GoPlus Security 또는 TokenSniffer와 같은 플랫폼을 활용하여 허니팟 또는 특이한 Mint 토큰의 징후를 검색합니다. 권리.
8. 개발자를 위한 방어 전략
개발자는 OpenZeppelin 표준 라이브러리를 사용하고 메모리 공간을 확보하기 위해 항상 "저장 공간 간격" 기술(빈 배열 uint256 private __gap; 생성)을 적용해야 합니다. 구현의 모든 변경 사항은 배포 전에 Hardhat 업그레이드 플러그인과 같은 자동화된 도구를 통해 메모리 레이아웃 호환성을 테스트해야 합니다.
9. 자주 묻는 질문(FAQ)
새 계약을 배포하는 대신 프록시 계약을 사용하는 이유는 무엇입니까? 프록시를 사용하면 사용자 및 통합 애플리케이션에 대해 단일 고정 계약 주소를 유지하는 데 도움이 되며 비용이 많이 드는 데이터 마이그레이션(마이그레이션)을 방지하고 업데이트나 버그 수정이 있을 때마다 사용자가 새 주소로 이동해야 하는 것을 방지합니다.
CALL과 DELEGATECALL 명령의 핵심 차이점은 무엇입니까?
CALL명령에서 대상 계약은 자체 메모리에서 실행됩니다. 이와 대조적으로DELEGATECALL은 대상 계약의 코드를 로드하지만 호출 계약의 "컨텍스트"에서 실행됩니다. 즉, 호출 계약의 메모리와 균형을 사용하고msg.sender를 유지합니다.투명 프록시가 UUPS보다 더 많은 가스를 소비하는 이유는 무엇입니까? 투명 프록시는 호출 방향(관리자 또는 로직)을 결정하기 위해 각 트랜잭션에서 호출자가 관리자인지 여부를 확인해야 합니다. UUPS는 업그레이드 논리가 구현 계약에 직접 있기 때문에 프록시에서 이 확인을 제거합니다.
프록시를 사용하여 프로젝트를 식별하는 방법 Etherscan에서 사용자는 "이것이 프록시입니까?" 버튼을 찾을 수 있습니다. 또는 "프록시로 읽기"/"프록시로 쓰기" 탭. 그렇다면 그것은 틀림없이 수권 계약이다.
저장소 간격이란 무엇입니까? 이는 향후 새 변수를 위한 저장 공간을 예약하기 위해 기본 계약에 빈 배열(예:
uint256 private __gap;)을 배치하여 레거시 계약의 메모리 위치 혼잡을 방지하는 기술입니다.프록시를 초기화하지 않으면 어떤 위험이 있나요? 배포 후
initialize함수가 즉시 호출되지 않으면 공격자가 이 함수를 직접 호출하여 계약의 소유자가 되어 모든 권한을 얻을 수 있습니다.프록시가 생성자를 사용할 수 없는 이유는 무엇입니까?
생성자의 코드는 배포 시 논리 계약 주소에서 한 번만 실행되는 반면 실제 사용자 상태는 프록시 주소에 있기 때문입니다.함수 선택기 충돌이란 무엇입니까? 이는 두 함수가 이름은 다르지만 4바이트 식별자가 동일한 현상입니다. 해커는 이를 이용하여 사용자를 속여 비즈니스 기능을 호출하도록 할 수 있지만 실제로는 위험한 관리 기능을 활성화합니다.
프록시 업그레이드가 안전한지 확인하는 방법 프로젝트는 Timelock 메커니즘(실행 시간 지연)과 결합된 다중 서명 지갑(Multisig)을 사용해야 커뮤니티가 새 소스 코드가 적용되기 전에 테스트할 시간을 가질 수 있습니다.
프록시 업그레이드를 비활성화할 수 있나요? 예. 개발자는 업그레이드 논리가 포함되지 않은 구현으로 업그레이드하거나 관리자 포기를 사용하여 프록시를 영구적인 불변 계약으로 만들 수 있습니다.
비콘 프록시는 일반 프록시와 어떻게 다릅니까? 각 프록시는 논리 주소를 저장하는 대신 중개 계약(비콘)을 가리킵니다. 비콘을 업데이트하면 단일 트랜잭션으로 수천 개의 종속 프록시가 동시에 업그레이드됩니다.
ProxyAdmin 계약의 역할은 무엇입니까? OpenZeppelin의 투명 프록시 모델에서
ProxyAdmin은 프록시 소유권을 가져오는 중개 계약으로, 일반 사용자 상호 작용과 별도로 업그레이드를 안전하게 관리하는 데 도움이 됩니다.프록시에서 백도어를 탐지하는 방법 사용자는 구현 소스 코드가 검증되었는지 확인하고 Slither와 같은 도구를 사용하여 자금을 인출하거나 거래를 차단할 수 있는
onlyOwner권한이 있는 함수를 검색해야 합니다.플래시 업그레이드 공격이란? 해커가 Proxy를 악성 코드로 업그레이드하고 돈을 훔친 후 단 한 번의 거래로 즉시 이전 버전으로 업그레이드하여 온체인 흔적을 지우는 공격 기법입니다.
가장 안전한 방법으로 프록시를 초기화하는 방법은 무엇입니까? 개발자는 원자성 초기화 프로세스를 사용해야 합니다. 즉, 해커의 "선택"을 피하기 위해 프록시 배포와
초기화함수 호출이 동일한 트랜잭션에서 발생한다는 의미입니다.
프록시 계약은 블록체인 생태계 개발을 위한 불가피한 기술 솔루션입니다. 그러나 이러한 유연성은 투명하게 관리되지 않으면 위험을 초래하기도 합니다. Tan Phat Digital은 거버넌스의 투명성과 사용자 신중함이 불안정한 Web3 세계에서 커뮤니티가 목표로 삼아야 할 진정한 '불변성'이라고 믿습니다.
공유








