CREATE 주소는 생성자 계정 주소와 그 계정의 생성 논스(nonce)를 RLP로 인코딩하고 Keccak-256으로 해시한 값의 마지막 20바이트로 정해집니다. CREATE2는 0xff, 배포자 주소, 32바이트 솔트(salt), keccak256(init_code)를 이어 붙여 해시한 값의 마지막 20바이트를 씁니다. CREATE2에서는 배포자와 솔트가 같아도 생성자 인수나 생성 바이트코드가 달라 초기화 코드 해시가 바뀌면 주소도 달라집니다. 예상 주소에 이미 논스나 코드가 있으면 생성이 실패하므로, 결정적 주소라는 말이 재배포가 늘 성공한다거나 그 주소의 실행 코드가 영원히 같다는 보장은 아닙니다.
CREATE 주소는 생성 순서에 묶입니다
외부 소유 계정(EOA)이 받는 주소 없는 생성 거래를 보내거나, 계약이 CREATE 옵코드를 실행하면 새 계정 주소는 생성자와 논스에서 나옵니다. 계약 계정의 생성 논스는 그 계약이 지금까지 배포한 순서를 반영합니다. 같은 바이트코드라도 앞서 생성이 하나 늘면 논스가 바뀌어 그 뒤 주소가 모두 달라집니다.
생성 거래에 담기는 데이터는 초기화 코드입니다. EVM은 초기화 코드를 실행하고, RETURN으로 돌려받은 바이트를 새 계정의 실행 코드로 저장합니다. 생성자 인수도 생성 바이트코드 뒤에 ABI 바이트로 붙습니다. 그래서 CREATE 주소는 초기화 코드 내용과 상관없이 생성자의 논스에만 기대지만, 배포 결과와 실패 여부는 초기화 실행에 달려 있습니다.
결정적 주소는 코드를 아직 실행하지 않고 위치를 계산할 수 있다는 뜻이지, 그 위치의 계약 동작까지 자동으로 신뢰할 수 있다는 뜻은 아닙니다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- CREATE 주소는 생성 순서에 묶입니다
외부 소유 계정(EOA)이 받는 주소 없는 생성 거래를 보내거나, 계약이 CREATE 옵코드를 실행하면 새 계정 주소는 생성자와 논스에서 나옵니다.
- CREATE2는 초기화 코드를 주소 약속에 넣습니다
EIP-1014가 정한 CREATE2의 해시 입력값은 정확히 0xff || deployer || salt || keccak256(init_code)입니다.
- 팩토리 배포 사례를 네 값으로 재현합니다
팩토리 F가 솔트 S, 생성 바이트코드 C, 생성자 인수 A로 지갑을 배포한다고 해 보겠습니다.
설명을 위한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
CREATE2는 초기화 코드를 주소 약속에 넣습니다
EIP-1014가 정한 CREATE2의 해시 입력값은 정확히 0xff || deployer || salt || keccak256(init_code)입니다. 고정 길이 접두어가 기존 CREATE의 RLP 주소 형식과 겹치지 않게 해 주고, 마지막 20바이트를 주소로 씁니다. 솔트는 옵코드 스택의 256비트 값이므로 화면에 보이는 문자열을 그대로 넣지 말고 실제 bytes32 인코딩을 확인합니다.
초기화 코드 해시는 배포 뒤의 실행 바이트코드 해시가 아닙니다. 같은 실행 코드를 돌려주더라도 생성자 로직이나 메타데이터, 인수가 다른 초기화 코드라면 주소가 달라질 수 있습니다. 반대로 해시 입력값이 같으면 같은 주소가 나오지만, 그 계정에 이미 논스나 코드가 있으면 EIP-684 조건에 따라 생성이 예외로 끝납니다.
| 항목 | CREATE | CREATE2 |
|---|---|---|
| 주소 입력 | 생성자·논스 | 0xff·배포자·솔트·초기화 코드 해시 |
| 배포 순서 영향 | 직접 영향 | 솔트가 같다면 없음 |
| 생성자 인수 영향 | 주소에는 없음 | 초기화 코드 해시를 통해 영향 |
| 사전 계산 | 논스를 알면 가능 | 해시 입력값을 알면 가능 |
| 기존 계정 충돌 | 생성 실패 | 생성 실패 |
팩토리 배포 사례를 네 값으로 재현합니다
팩토리 F가 솔트 S, 생성 바이트코드 C, 생성자 인수 A로 지갑을 배포한다고 해 보겠습니다. 먼저 init=C||ABI(A)를 정확히 만들고 H=keccak256(init)을 계산합니다. 이어서 keccak256(0xff||F||S||H)의 마지막 20바이트를 취합니다. 라이브러리 연결 주소나 컴파일러 메타데이터가 C에 들어가면 같은 소스라도 H가 달라질 수 있습니다.
프런트엔드는 예상 주소로 토큰을 미리 보내기 전에 체인 ID, 팩토리 주소, 팩토리 실행 코드 해시, 솔트 인코딩, 초기화 코드 해시를 서명 화면에 보여 줘야 합니다. 다른 체인에 같은 F가 없거나 팩토리 코드가 다르면 계산 결과의 의미도 달라집니다. 주소 문자열 하나만 비교하지 않습니다.
- 배포 체인과 팩토리 주소·코드 해시를 고정합니다.
- 생성 바이트코드와 생성자 ABI 바이트를 합칩니다.
- 솔트를 정확한 bytes32 값으로 맞춥니다.
- EIP-1014 해시 입력값과 예상 주소를 따로 계산해 봅니다.
- 배포 뒤 실행 코드 해시와 초기화 상태를 확인합니다.
미리 계산한 주소에도 충돌과 선점 위험이 있습니다
상태 채널이나 계정형 지갑은 아직 배포되지 않은 CREATE2 주소를 참여자 식별에 쓸 수 있습니다. 하지만 그 주소에 ETH나 토큰을 먼저 보냈다면, 올바른 팩토리만 원하는 초기화 코드를 배포할 수 있는지 검증해야 합니다. 누구나 부를 수 있는 팩토리가 솔트 소유권을 검사하지 않으면 제3자가 다른 인수로 먼저 거래를 낼 수 있습니다.
배포자와 솔트가 같아도 초기화 코드가 다르면 주소가 다르므로, 솔트만 선점하는 경우와 같은 주소를 선점하는 경우는 구분합니다. 같은 해시 입력값의 주소가 이미 만들어져 논스나 코드가 남아 있으면, 같은 거래 안에서 다시 생성해도 실패합니다. CREATE2를 주소 덮어쓰기 기능으로 설명하면 안 됩니다.
SELFDESTRUCT 뒤 재배포 가정은 포크에 따라 깨집니다
예전의 변신 계약(metamorphic contract) 패턴은 코드를 지운 뒤 같은 CREATE2 주소에 새 코드를 배포하는 흐름을 이용했습니다. 칸쿤(Cancun)의 EIP-6780 이후에는 기존 계약에서 SELFDESTRUCT를 호출해도 대개 코드와 저장소가 지워지지 않으므로, 다음 거래에서 재배포한다는 전제가 성립하지 않습니다.
생성한 바로 그 거래 안에서 SELFDESTRUCT하는 경우는 예외지만, 장기 업그레이드 수단으로 기대서는 안 됩니다. 배포 시스템은 대상 체인의 포크, 계정의 논스·코드, 영수증 상태를 확인하고 프록시 업그레이드와 CREATE2 재배포를 서로 다른 모델로 다룹니다.
자주 묻는 질문
CREATE2 솔트만 같으면 같은 주소인가요?
아닙니다. 배포자 주소와 초기화 코드 해시도 같아야 하며, 그 체인에서 해당 배포자의 배포 상태도 확인해야 합니다.
실행 바이트코드 해시로 CREATE2 주소를 계산하나요?
아닙니다. 생성자를 실행하기 전 초기화 코드 전체의 Keccak-256 해시를 씁니다.
계산한 주소에 미리 자금을 보내도 안전한가요?
팩토리 코드와 권한, 솔트와 초기화 코드를 먼저 검증해야 합니다. 해시 입력값이 틀렸거나 배포가 실패하면 자금에 접근하지 못할 수 있습니다.
더 깊이 읽기
본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.



