EIP-684 주소 충돌 시 컨트랙트 생성 실패 처리 (Revert creation in case of collision)

최종 확정 · 보안·프라이버시 · 원문 상태 Final · 2023-03-20 작성

이미 논스나 코드가 있는 주소에 컨트랙트를 생성하려고 하면 생성을 반드시 실패시킵니다. 배포된 코드가 나중에 바뀌는 공격을 막습니다.

왜 필요한가

한번 배포된 코드는 바뀌지 않는다는 것이 스마트 컨트랙트의 핵심 전제입니다. 그런데 기존 규칙에서는 이미 코드가 있는 주소에 다시 계정을 '생성'하는 길이 막혀 있지 않았습니다. 계산 능력이 충분한 공격자라면 어떤 주소에 컨트랙트 코드를 배포해 두고 나중에 같은 주소에서 생성을 다시 일으켜 저장된 코드를 임의의 다른 코드로 바꿀 수 있습니다. 그렇게 되면 자금을 훔치거나 다른 악의적인 동작을 심을 수 있습니다. 이 EIP는 생성하려는 주소에 이미 0이 아닌 논스(nonce)나 코드가 있으면 생성 자체를 실패시켜 배포된 코드의 불변성을 프로토콜 규칙으로 강제합니다.

무엇이 바뀌나

지금

EIP-684 이후

누구에게 영향이 있나

심층 설명

충돌 판정 조건과 실패 방식

생성 트랜잭션, CREATE 명령어, CREATE2 명령어, 그 밖의 어떤 이유로든 컨트랙트 생성이 시도될 때, 대상 주소(destination address)에 0이 아닌 논스(nonzero nonce) 또는 0이 아닌 코드 길이(nonzero code length)가 있으면 생성은 반드시(MUST) 실패해야 합니다. 실패 방식은 초기화 코드(init code)의 첫 바이트가 잘못된 명령어(invalid opcode)인 것처럼 처리하는 것입니다. 즉 별도의 예외 경로를 만들지 않고 기존의 실행 실패 의미론을 그대로 씁니다.

모든 기존 블록에 소급 적용

이 규칙은 모든 기존 블록에 소급해(retroactively) 적용되어야 합니다(MUST). 특정 포크 블록 이후에만 켜지는 것이 아니라 체인 전체 이력에 같은 충돌 처리 규칙이 적용됩니다. 동시에 이 변경은 실행 계층 업그레이드이므로 하드포크가 필요합니다.

막으려는 공격

코드가 바뀌지 않는다는 것이 스마트 컨트랙트의 핵심 전제입니다. 그러나 충분한 계산 능력이 있으면 공격자는 어떤 주소에 저장된 코드를 다른 코드로 바꿀 수 있습니다. 컨트랙트 코드를 먼저 배포해 두고 나중에 그 주소에 계정을 다시 '생성'해 코드를 임의로 교체하는 방식입니다. 이렇게 되면 자금 탈취 등 악의적 행위가 가능합니다. 이 EIP는 그 생성 경로 자체를 막아 배포된 코드의 불변성을 강제하는 보안 업그레이드입니다.

테스트 케이스

제네시스 할당으로 두 계정을 둡니다. 0xd0bBEc6D2c628b7e2E6D5556daA14a5181b604C5는 잔액 1 이더, 논스 0, 코드 없음이고, 0x7658771dc6Af74a3d2F8499D349FF9c1a0DF8826은 잔액 0, 논스 1, 코드 0xB0B0FACE입니다. 외부 계정 0xd0bBEc6...이 보내는 첫 트랜잭션(해시 227bcc6959669226360814723ed739f1214201584b6a27409dfb8228b8be5f59)에서 솔트 없이 만든 컨트랙트 생성은 revert해야 합니다.

상태와 콜 결정

이 EIP의 상태는 Final입니다. 2026년 9월 14일 ACDT #96에서는 레거시 테스트 PR #18을 병합해 충돌 처리를 옐로페이퍼와 EIP-684의 방식으로 되돌리기로 확정했습니다. 다만 블록 접근 목록 BAL(Block Access List)의 충돌 처리는 헤고타(Hegota)의 EIP-8253이 결론 날 때까지 정의하지 않고 남겨 두기로 했습니다.

EIP 원문 · ← EIPs