불변성은 오랫동안 블록체인 기술의 핵심 특성이자 신뢰의 기반으로 여겨져 왔으며, 일단 소스 코드가 네트워크에 배포되면 어떤 개인이나 조직도 확립된 규칙을 방해하거나 변경할 수 없도록 보장합니다. 그러나 Tan Phat Digital의 연구에 따르면 최근 몇 년간 분산형 생태계의 실제 운영을 통해 절대 불변성이 지속 가능한 개발에 중요한 장벽인 것으로 나타났습니다. 패치할 수 없는 심각한 보안 취약성, 업데이트할 수 없는 규정 변경, 새로운 기능 추가의 필요성으로 인해 개발자 커뮤니티는 주소 및 데이터 무결성을 훼손하지 않고 스마트 계약을 '업그레이드'할 수 있는 방법을 모색하게 되었습니다.
이 연구에서는 인기 있는 프록시 모델부터 논란의 여지가 있는 Metamorphic 기술에 이르기까지 배포 후 논리 변경을 허용하는 기술을 심층적으로 분석하고 보안 위험 및 관련 거버넌스 장벽의 위험을 평가합니다.
불변성과 데이터 무결성의 역설 가변성의 필요성
기술적으로, 이더리움과 같은 블록체인의 블록에 영구적으로 저장된 스마트 계약의 바이트코드는 변경할 수 없습니다. 각 계약 주소는 고정된 코드 조각과 연결되어 있습니다. 그러나 프로그래머는 상태 저장과 논리 실행을 완전히 분리하여 가변성을 시뮬레이션할 수 있습니다. 이로 인해 사용자가 고정된 '쉘'과 상호작용하지만 실제 행동은 가변적인 개체에 의해 주도되는 혼란스러운 계층이 생성됩니다.
가변성의 필요성은 보안 유지 관리, 제품 진화, 위험 관리라는 세 가지 주요 요소에서 발생합니다. 작은 논리 오류라도 즉시 해결하지 않으면 수백만 달러의 자산 손실로 이어질 수 있습니다. 전통적인 금융 시스템에서는 유지 관리를 위한 다운타임이 일반적이지만, 프로토콜이 연중무휴 24시간 운영되는 블록체인에서는 논리 업그레이드를 통한 '핫픽스' 기능이 프로젝트 생존에 매우 중요합니다.
블록체인 플랫폼 간의 디자인 철학 비교
현재 인기 있는 플랫폼 간의 디자인 사고 방식의 차이점:
이더리움 (EVM):
기본 상태: 불변.
논리 변경 메커니즘: 프록시 및
delegatecall사용.업그레이드 접근 방식: 애플리케이션 계층(애플리케이션 패턴).
투명성: 소스 코드 확인에 따라 다름 프록시.
Stellar(Soroban):
기본 상태: 변경 가능.
논리 변경 메커니즘: WASM 바이트코드를 직접 변경합니다.
업그레이드 접근 방식: 프로토콜 수준.
투명성: 계약 메타데이터에 내장되어 있습니다.
이 차이점은 새로운 추세를 나타냅니다. Ethereum에는 복잡한 디자인 패턴이 필요하지만 Soroban은 계약이 프로토콜 수준에서 자체 바이트코드를 수정할 수 있도록 허용하여 잘못된 프록시 구현으로 인해 발생하는 위험을 줄이는 데 도움이 됩니다.
참조: 악성 스마트 계약으로부터 보호
프록시 계약 인프라 및 Opcode DELEGATECALL
EVM 호환 네트워크의 대부분의 업그레이드 기술은 단일 opcode인 delegatecall을 기반으로 합니다. 계약 A(프록시)가 계약 B(구현)에 대한 delegatecall을 실행하면 계약 B의 코드가 실행되지만 실행 컨텍스트(storage, Balance, msg.sender)는 전적으로 계약 A에 속합니다.
이 메커니즘을 통해 개발자는 새로운 버전의 로직(구현 V2)을 배포하고 V2를 가리키도록 프록시의 주소 변수를 간단히 업데이트할 수 있습니다. 사용자 관점에서 볼 때 대화형 계약 주소는 동일하고 계정 잔액 및 관련 데이터는 영향을 받지 않지만 처리 규칙이 변경되었습니다.
최신 프록시 모델에 대한 심층 분석
프록시 배포에는 가스 비용, 관리 보안 및 확장성을 신중하게 고려해야 합니다.
투명 프록시 패턴(TPP)
이 모델은 "기능"을 해결합니다. 호출자 신원을 기준으로 액세스를 분리하여 선택기 충돌' 문제를 해결합니다. 호출자가 관리자인 경우 프록시의 관리 기능만 볼 수 있습니다. 사용자인 경우 통화가 구현에 위임됩니다.
단점: 관리자 신원 확인을 수행해야 하기 때문에 거래당 약 2,100의 추가 가스 비용이 듭니다.
UUPS(Universal Upgradeable Proxy Standard)
UUPS(EIP-1822)는 업그레이드 논리를 구현 계약 자체에 넣습니다. 이제 프록시는 최소한의 코드 조각일 뿐입니다.
장점: 최종 사용자에게는 가스가 매우 절약됩니다(추가 가스 비용은 약 100에 불과함).
위험: 새 업그레이드에
upgradeTo기능이 없으면 계약이 "브릭"(영구적으로 잠김)되어 더 이상 업그레이드할 수 없습니다.
비콘 프록시 패턴
이 솔루션은 유사한 계약의 대량 배포에 적합합니다. 프록시는 논리적 주소를 저장하지 않지만 중간 계약(Beacon)을 가리킵니다. Beacon을 업데이트하면 수천 개의 종속 계약이 동시에 업데이트됩니다. 이는 효과적인 메커니즘이지만 엄청난 "중앙 집중식 약점"을 만듭니다.
다이아몬드 표준(EIP-2535)
이것은 단일 프록시(다이아몬드)가 다양한 구현(패싯)에 위임할 수 있는 가장 복잡한 업그레이드 아키텍처입니다.
다이아몬드 프록시: 단일 상호 작용 지점, 매핑 저장 기능.
Facets: 독립적인 논리적 계약은 시스템이 EVM의 24KB 제한을 극복하는 데 도움이 됩니다.
DiamondCut: 관리 기능을 사용하면 특정 기능을 추가, 교체 또는 삭제할 수 있습니다.
Diamond Loupe: 인터페이스를 사용하면 현재 구조를 확인할 수 있습니다. Diamond.
자세히 보기: 스마트 계약 감사란 무엇입니까?
경계 허물기: 변형 계약 및 CREATE2
논리를 변경하는 보다 극단적인 방법은 "변형 계약"입니다. 프록시와 달리 이 기술을 사용하면 CREATE2 opcode를 사용하여 동일한 주소에서 바이트코드를 완전히 교체할 수 있습니다.
"변환" 절차에는 지정되지 않은 init_code(초기화 코드)를 사용하는 작업이 포함됩니다. 고정된 논리를 포함하는 대신 init_code를 프로그래밍하여 다른 계약을 호출하고 새 실행 가능 바이트코드를 검색할 수 있습니다. 변경이 필요한 경우 개발자는 SELFDESTRUCT 명령을 실행하여 기존 계약을 삭제하고 동일한 salt 값과 함께 CREATE2를 사용하여 동일한 주소에 새 코드를 배포합니다. 이 기술은 상태(스토리지)를 삭제하고 감사 조직을 속이는 데 악용될 수 있기 때문에 위험한 것으로 간주되는 경우가 많습니다.
변수 계약의 보안 위험 매트릭스
논리 변경을 허용하면 특정 보안 취약점이 발생합니다.
저장소 레이아웃 충돌: 새 버전이 변수 순서를 변경하여 잘못된 데이터를 덮어쓸 때 발생합니다. 예를 들어, Audius 해킹(2022)에서는 초기화 플래그를 덮어쓰는 새 변수로 인해 프로젝트에 600만 달러의 비용이 발생했습니다.
초기화 취약점: 프록시는
생성자를 사용하지 않으므로initialize()함수가 필요합니다. 이 함수를 호출하는 것을 잊어버리면 공격자가 관리자 권한을 탈취할 수 있습니다. Wormhole 해킹(3억 2천만 달러)이 이러한 실수의 전형적인 예입니다.관리 백도어: 일부 사기 프로젝트는 자본을 유치한 후 의도적으로 프록시를 사용하여 악성 코드를 설치합니다.
인기 있는 백도어 유형:
백도어 발행: 관리자 무한한 토큰을 생성하여 시장에 출시합니다.
블랙리스트/동결: 사용자가 토큰을 인출하거나 판매할 수 없도록 계정을 잠급니다.
Drainage Logic: 자산을 공격자의 지갑으로 직접 전송하도록 인출 기능을 수정합니다.
프록시 리디렉션: 구현 주소를 악성으로 리디렉션합니다. 계약.
거버넌스 전략 및 다층 방어
유연성과 안전성의 균형을 맞추기 위해 Tan Phat Digital은 프로젝트에 엄격한 거버넌스 프로세스를 적용할 것을 권장합니다.
다중 서명 사용: 업그레이드 권한은 개별 약점을 제거하기 위해 2/3 또는 3/5 승인 임계값을 가진 다중 서명 지갑(예: Gnosis Safe)에 보유되어야 합니다.
시간 잠금 메커니즘: 모든 업그레이드 명령에 대해 최소 24시간에서 최대 7일의 시간 잠금을 적용합니다. 이를 통해 커뮤니티는 소스 코드를 검사하거나 이상이 감지되면 자산을 회수할 수 있는 시간을 갖게 됩니다.
저장 공간 간격 유지: 향후 업그레이드 시 충돌을 일으키지 않고 변수를 추가할 수 있도록 저장 공간에 간격을 두십시오.
지속적인 감사: 각 로직 업그레이드는 새로운 프로젝트로 처리되어야 하며 독립적인 감사 프로세스를 거쳐야 합니다.
자주 묻는 질문(FAQ)
1. 프록시 계약이란 무엇이며 왜 중요한가요?
프록시는 데이터와 자산을 보유하는 중개 계약이며, 실행 논리는 다른 계약에 있습니다. 계약 주소를 변경하지 않고도 논리 업데이트가 가능하므로 사용자 경험과 프로토콜 연속성을 유지하는 데 도움이 됩니다.
2. Solidity에서 Vyper로 계약을 업그레이드할 수 있나요?
예. Solidity와 Vyper는 모두 EVM에서 실행되는 바이트코드로 컴파일되기 때문입니다. 새로운 Vyper 버전의 저장소 레이아웃이 이전 Solidity 버전과 정확히 일치하는 한, 로직 교체는 기술적으로 가능합니다.
3. Etherscan에서 계약이 프록시인지 확인하는 방법은 무엇입니까?
사용자는 Etherscan의 "프록시 계약 확인" 도구를 사용할 수 있습니다. EIP-1967 표준을 준수하는 계약에는 "프록시로 읽기" 또는 "프록시로 쓰기" 탭이 있어 뒤에서 실행되는 실제 구현 주소를 볼 수 있습니다.
4. 24KB 소스 코드 제한은 무엇이며 Diamond Standard는 이를 어떻게 해결합니까?
EVM은 계약의 바이트코드 크기를 최대 24KB로 제한합니다. Diamond Standard(EIP-2535)를 사용하면 로직을 여러 "패싯"(계약 부분)으로 분할하여 단일 주소로 거의 무제한의 로직을 실행할 수 있습니다.
5. "스토리지 충돌"이란 정확히 무엇입니까?
프록시 계약과 논리 계약이 실수로 두 개의 다른 변수를 저장하기 위해 메모리에서 동일한 위치(슬롯)를 사용하는 경우입니다. 이로 인해 한 변수가 다른 변수를 덮어쓰게 되어 심각한 논리 오류가 발생하거나 공격자가 이를 장악할 수 있습니다.
6. 업그레이드할 때 프로젝트에 Timelock이 필요한 이유는 무엇입니까?
Timelock은 업그레이드가 적용되기 전에 대기 기간(보통 24시간 이상)을 생성합니다. 이를 통해 커뮤니티는 반응하고, 소스 코드를 확인하고, 새 업데이트를 신뢰하지 않는 경우 철회할 시간을 갖게 됩니다.
7. 투명 프록시와 UUPS는 어떻게 다른가요?
투명 프록시는 업그레이드 로직을 프록시에 넣고 더 많은 가스를 소비하지만 관리자 권한을 명확하게 분리하기 때문에 더 안전합니다. UUPS는 업그레이드 논리를 구현에 넣습니다. 이는 더 많은 가스를 절약하지만 업그레이드가 실패하면 계약이 다시는 복구되지 않기 때문에 위험이 높습니다.
8. Metamorphic 계약은 일반 프록시와 어떻게 다릅니까?
프록시는 해당 주소에 바이트코드를 유지하고 가리키는 논리 주소만 변경합니다. Metamorphic 계약은 사이트 자체의 전체 소스 코드를 직접 대체하지만 기존 데이터와 잔여 데이터를 모두 삭제합니다.
9. EIP-6780은 계약 업그레이드에 어떤 영향을 미치나요?
EIP-6780은 SELFDESTRUCT 명령이 계약을 시작한 동일한 트랜잭션 내에서만 작동하도록 제한합니다. 이는 새로운 코드를 재배포하기 위해 언제든지 계약을 파기하는 데 의존했던 대부분의 오래된 "변형" 기술을 비활성화합니다.
10. "Storage Gap"은 무엇에 사용됩니까?
기본 계약에 배치된 빈 변수(일반적으로 uint256 __gap)의 배열입니다. 향후 업그레이드 시 개발자가 레거시 계약의 스토리지 레이아웃을 왜곡하지 않고 새로운 변수를 추가할 수 있도록 스토리지 공간을 예약합니다.
11. 계약을 "업그레이드 가능"에서 "불변"으로 변환할 수 있나요?
예. 개발자는 최종 업그레이드를 수행하여 업그레이드 기능을 제거하거나 관리자(소유자)를 "0" 주소(0x0)로 이동할 수 있습니다. 업그레이드 기능이 사라지면 로직은 영원히 잠깁니다.
12. "초기화되지 않은 프록시"의 위험은 무엇입니까?
개발자가 배포 직후 초기화 함수(initialize)를 호출하는 것을 잊어버린 경우 누구나 이를 호출하여 계약 소유자가 될 수 있습니다. 웜홀 해킹은 이 오류로 인해 수억 달러의 손실이 발생할 뻔한 전형적인 예입니다.
13. 실제로 업그레이드를 받는 계약의 비율은 얼마나 되나요?
연구에 따르면 이더리움 계약 중 약 3%만이 업그레이드를 위해 설계되었으며, 그 중 약 0.34%만이 배포 후 실제로 업그레이드를 거칩니다.
14. Beacon Proxy는 언제 사용되나요?
수천 개의 동일한 계약(예: Smart Wallet)을 배포해야 할 때 사용됩니다. 각 계약을 업데이트하는 대신 "Beacon"에서 단일 주소만 업데이트하면 모든 지갑의 논리가 동시에 변경됩니다.
15. 프록시 대신 "계약 마이그레이션"을 사용해야 하는 경우는 언제인가요?
스토리지 슬롯 충돌로 인해 프록시가 처리할 수 없는 핵심 데이터 구조(예: ERC-20에서 ERC-777 표준으로 변경)를 변경해야 하는 경우. 이 시점에서 완전히 새로운 계약을 배포하고 사용자에게 자산을 새 주소로 전송하도록 요청해야 합니다.
스마트 계약의 가변성의 미래
업그레이드 기술의 개발은 정적 블록체인 소스 코드에 대한 고정관념을 깨뜨렸습니다. 불변성이 궁극적인 이상이지만, 통제된 가변성은 보안 결함과 시장 변화에 대처하는 데 필수적입니다.
향후 추세는 DAO를 통한 업그레이드 권한의 분산화와 OpenZeppelin 업그레이드 플러그인과 같은 자동화된 테스트 도구의 사용이 될 것입니다. 투명하고 적절하게 구현된 가변성은 블록체인의 가치를 저하시키지 않고 오히려 회복력이 있고 지속적으로 진화할 수 있는 생태계를 조성합니다.
공유








