본문으로 이동

CREATE2 컨트랙트 주소 검증 방법

CREATE2는 배포자, salt와 초기화 코드 해시로 주소를 예측하지만, 검증에는 체인별 팩토리, 바이트코드, 배포, 프록시와 소유권 증거가 필요합니다.

업데이트

교육 목적의 참고 자료일 뿐 투자 또는 보안 자문이 아닙니다. 예측 주소, 빈 계정, 체크섬 또는 팩토리 라벨은 배포, 코드, 제어권, 소유권이나 안전성을 증명하지 않습니다.

핵심 답변

CREATE2는 특정 배포 컨트랙트가 32-byte salt와 정확한 init_code의 해시로 생성할 주소를 예측합니다. 프로토콜 공식은 address = keccak256(0xff || deployer(20 bytes) || salt(32 bytes) || keccak256(init_code))[12:]입니다. 85-byte preimage를 해시한 뒤 마지막 20 bytes를 취합니다. deployer는 CREATE2를 실행하는 팩토리이며 팩토리를 호출한 지갑과 다를 수 있습니다.

init_code는 생성 바이트코드와 ABI로 인코딩한 생성자 인자로 구성되며 한 번 실행되어 런타임 바이트코드를 만듭니다. 컴파일러 버전, 최적화 설정, 연결 라이브러리, 메타데이터, 생성자 인자 또는 팩토리 진입점이 해시를 바꿀 수 있습니다. 런타임 코드는 결과이지 CREATE2 입력이 아닙니다. 배포자, salt, 초기화 코드, EVM 규칙과 체인 상태가 같을 때만 주소를 비교할 수 있습니다.

카운터팩추얼 주소는 코드가 존재하기 전에 자금을 받을 수 있지만 아직 검증된 제어 로직이 없습니다. 예측은 배포, 소유권, 권한, 최종성 또는 안전성을 뜻하지 않습니다. 대상 체인과 블록에서 팩토리 바이트코드와 calldata, 영수증과 이벤트, eth_getCode, nonce, 스토리지, 잔액, 프록시 구현체, 초기화와 소유자를 확인해야 합니다.

작동 방식

체인 또는 도메인, 포크 규칙, RPC와 블록, 팩토리 주소와 런타임 해시, 원시 salt, 정확한 초기화 바이트, 생성자 인코딩, 컴파일러와 연결 라이브러리를 고정합니다. keccak256(init_code)85-byte preimage를 다시 계산하고 ABI 패딩, 엔디언, 체크섬 및 마지막 20바이트 추출을 확인합니다.

그 다음 팩토리 호출과 value를 디코드합니다. 의도한 팩토리, 진입점, salt 도메인, 생성자, 소유자와 초기화가 묶여 있는지 확인합니다. 미니멀 프록시는 구현체 주소를 포함한 클론 생성 바이트코드를 해시해야 하며 구현체 런타임 바이트코드를 해시하면 안 됩니다. 프록시는 구현체, 관리자, 스토리지 슬롯과 업그레이드 정책을 별도로 검증합니다.

EIP-684에 따라 대상 nonce가 0이 아니거나 코드가 비어 있지 않으면 생성은 리버트됩니다. 생성자가 실패해도 성공한 배포가 남지 않습니다. 이후 SELFDESTRUCT와 재배포 의미는 포크 규칙에 따라 달라지므로 “코드는 언제든 마음대로 교체할 수 있다”는 오래된 가정에 의존하지 마세요.

배포 증거는 트랜잭션 포함과 상태, 발생 이벤트, 코드와 nonce, 스토리지와 잔액, 안전하거나 최종 확정된 체인 상태의 계층으로 나뉩니다. RPC 성공 응답이나 예측 체크섬은 영수증과 상태 검증을 대체할 수 없습니다. 다른 체인에 복사된 동일 주소도 코드, 소유자, 스토리지와 자산이 다를 수 있습니다.

다음 절차를 사용합니다.

  1. 체인, 포크, RPC와 블록, 팩토리 또는 배포자 주소와 런타임 해시, salt 바이트, 초기화 코드, 생성자 인자, 컴파일러와 연결 라이브러리를 고정합니다.
  2. 초기화 코드 해시와 정확한 CREATE2 프리이미지를 계산하고 폭, 패딩, 0xff, 마지막 20바이트와 체크섬을 확인합니다.
  3. 팩토리 calldata와 value를 디코드하고 예측 주소, 소유자, 초기화, 프록시 대상과 권한을 비교합니다.
  4. 올바른 체인에서 영수증, 상태, 이벤트, eth_getCode, nonce, 잔액과 스토리지를 확인하고 미배포와 충돌 상태를 기록합니다.
  5. 팩토리, 프록시, 구현체, 관리자, 초기화, 업그레이드, 싱글턴 팩토리 가정을 점검하고 ERC-1167 대상도 확인합니다.
  6. 생성자 실패, nonce/코드 충돌, 포크에 민감한 재배포, 중첩 팩토리와 체인 도메인 또는 재생 공격 가정을 시험합니다.
  7. 자금 공급이나 서명 전에 사람이 읽는 금액과 원시 금액을 대조하고, 배포 후 코드 해시, 소유자, 구현체, 역할, 이벤트와 최종성을 모니터링합니다.

예시

  • EIP-1014 벡터: 배포자 0x0000000000000000000000000000000000000000, 모두 0인 salt와 초기화 코드 0x000x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38을 산출합니다.
  • 생성자 바인딩: 배포자와 salt를 고정해도 ABI로 인코딩한 생성자 인자 하나를 바꾸면 keccak256(init_code)와 예측 주소가 바뀝니다. 런타임 바이트코드를 해시하면 잘못된 대상을 검증하게 됩니다.
  • 충돌: 대상 nonce가 0보다 크거나 코드가 비어 있지 않으면 EIP-684에 따라 CREATE2는 리버트해야 합니다. 코드와 nonce가 0이어도 자금만 있는 주소는 카운터팩추얼일 뿐 검증되지 않았습니다.
  • 미니멀 프록시: ERC-1167 클론 주소는 구현체 주소를 포함한 클론 생성 바이트코드를 해시합니다. 구현체 런타임 코드를 해시하면 무관한 예측이 나옵니다.

위험

  • 잘못된 팩토리 또는 배포자를 사용합니다.
  • salt 폭, 패딩, 엔디언 또는 도메인 인코딩이 잘못되었습니다.
  • 초기화 코드와 런타임 바이트코드를 혼동합니다.
  • 생성자 인자가 누락되거나 순서가 바뀝니다.
  • 팩토리 진입점, value 또는 calldata가 다릅니다.
  • 프록시 또는 delegate 대상이 의도한 구현체가 아닙니다.
  • 체인, 포크 또는 EVM 도메인이 다릅니다.
  • 기존 nonce가 충돌을 일으킵니다.
  • 기존 코드가 충돌을 일으킵니다.
  • 오래된 SELFDESTRUCT 재배포 가정을 사용합니다.
  • 중첩 CREATE2가 유효한 배포자를 바꿉니다.
  • CREATE와 CREATE2 공식을 혼용합니다.
  • ERC-1167 구현체 대상을 확인하지 않습니다.
  • 싱글턴 팩토리 주소나 배포 가정을 검증하지 않습니다.
  • 구현체 업그레이드나 관리자 제어가 동작을 바꿉니다.
  • 컴파일러, 메타데이터, 라이브러리 또는 소스 산출물이 다릅니다.
  • 영수증, 멤풀, 실패와 최종성 상태를 혼동합니다.
  • 체크섬 또는 UI 오염이 잘못된 주소를 숨깁니다.
  • 미리 자금이 공급된 카운터팩추얼 자금에 소유권 증거가 없습니다.
  • EIP-7702, 재생 공격, 가스, 서비스 거부 또는 오래된 모니터링 가정이 잘못되었습니다.

흔한 오해

  • “빈 주소는 안전하거나 소유된 주소다.” 코드나 검증된 제어자가 없을 수 있습니다.
  • “주소는 salt만으로 결정된다.” 배포자와 초기화 코드 해시도 똑같이 주소에 묶입니다.
  • “CREATE2는 런타임 바이트코드를 해시한다.” 생성자 인자를 포함한 생성 코드를 해시합니다.
  • “두 체인의 같은 주소는 같은 코드와 통제권을 뜻한다.” 체인 상태와 배포를 각각 확인해야 합니다.
  • “예측에 성공하면 배포와 안전성이 증명된다.” 영수증, 코드, 상태, 권한과 최종성이 실제 존재를 확정합니다.

관련 주제

출처

탐색

위키 검색...