EIP-7819 SETDELEGATE 명령어 (SETDELEGATE instruction)
Hegota 포함 제외 (DFI) · EVM·실행 · 원문 상태 Draft · 2024-11-18 작성
컨트랙트가 EIP-7702 방식의 위임 표시자를 직접 만들고 바꿀 수 있는 새 EVM 명령어 SETDELEGATE(0xf6)를 추가합니다. 클론이나 프록시 대신 23바이트 위임으로 같은 코드를 재사용합니다.
왜 필요한가
같은 코드를 여러 주소에 배포하는 일은 온체인에서 매우 흔하고 스마트 계정 지갑이 대표적입니다. 배포 비용을 줄이려고 ERC-1167 클론이나 업그레이드 가능한 프록시를 쓰는데, 클론은 가볍지만 구현 주소를 바꿀 수 없고 프록시는 바꿀 수 있는 대신 호출마다 스토리지에서 구현 주소를 읽는 비용이 듭니다. 둘 다 받은 호출 데이터를 메모리에 복사해 위임 호출을 수행하는 EVM 코드가 필요합니다. 게스(Geth) 팀 조사(EthCC[9] "Not all state is equal")에 따르면 배포된 약 5천만 개 컨트랙트의 97.1%가 이미 배포된 적 있는 코드이고 고유 바이트코드의 28.6%는 1KiB 미만의 작은 코드입니다. 클론과 프록시가 그 상당수를 차지할 가능성이 높아, 이 역할을 프로토콜 차원에서 더 작고 싸게 처리할 방법이 필요합니다.
무엇이 바뀌나
지금
- 같은 코드를 재사용하려면 ERC-1167 클론이나 약 708바이트짜리 ERC-1967 프록시를 배포합니다
- 클론은 업그레이드가 불가능하고 프록시는 호출마다 스토리지에서 구현 주소를 읽습니다
- 호출 전달이 컨트랙트 코드 안에서 일어나 호출마다 추가 가스가 듭니다
EIP-7819 이후
- 컨트랙트가 SETDELEGATE 한 번으로 23바이트 위임 계정을 만듭니다
- 스토리지 조회 없이 업그레이드할 수 있고 팩토리가 재설정을 막으면 고정형 계정도 됩니다
- 호출 전달을 프로토콜이 처리해 서명 검증, 토큰 콜백 등 모든 호출의 가스가 줄어듭니다
누구에게 영향이 있나
- 지갑·스마트 계정 개발자: 팩토리 하나로 업그레이드 가능 계정과 불가능 계정을 모두 기존 클론보다 싸게 배포하고 업그레이드 로직을 계정이 아닌 팩토리에서 관리할 수 있습니다.
- 사용자: 스마트 계정을 거치는 호출마다 들던 전달 비용이 사라져 상호작용 가스가 줄어듭니다.
- 클라이언트 팀: 새 옵코드 0xf6을 구현해야 하지만 반복 배포되는 클론·프록시가 23바이트 위임으로 바뀌면 상태 증가가 완화됩니다.
- ERC-4337 생태계: 엔트리포인트 새 버전에 맞춰 업그레이드가 필요한 스마트 계정을 스토리지 조회 비용 없이 운영할 수 있습니다.
심층 설명
명령어 동작 10단계
0xf6에 추가되는 SETDELEGATE는 다음 순서로 동작합니다. EMPTY_ACCOUNT_COST 가스를 차감하고 static-mode 프레임이면 중단합니다. 스택에서 salt와 target을 꺼내 location = keccak256(DESIGNATOR ++ address ++ salt)[12:]를 계산하고 location을 EIP-2929의 accessed_addresses에 추가합니다. location의 코드가 비어 있지도 않고 0xEF0100으로 시작하지도 않으면(위임 표시자가 아니면) 중단합니다. location이 이미 트라이에 존재하면 EMPTY_ACCOUNT_COST - BASE_COST를 환불 카운터에 더합니다. 코드를 DESIGNATOR ++ target으로 설정하되, target이 0x0이면 코드를 지우고 코드 해시를 빈 해시로 되돌립니다. 논스가 0이면 1로 올리고 location을 스택에 푸시합니다. target은 정확히 20바이트여야 하며 짧으면 앞을 0으로 채우고 길면 상위 바이트를 자릅니다. 결과 코드는 EIP-7702에 따라 정확히 23바이트입니다.
가스 비용과 파라미터
파라미터는 EIP-7702와 같습니다. DESIGNATOR는 0xef0100, EMPTY_ACCOUNT_COST는 25000, BASE_COST는 12500입니다. 실제로는 7702보다 하는 일이 적습니다. 서명 복구가 없고 트랜잭션 수준에서 이미 지불한 것 외의 별도 콜데이터가 없으며 9단계의 초기 1 설정을 빼면 논스 갱신도 없습니다. 따라서 비용을 더 낮출 수도 있지만 단순함을 위해 7702 값을 재사용합니다. 이 값은 CREATE·CREATE2 비용보다 낮아 의도한 용도에서 경쟁력이 있습니다.
주소 유도와 기존 주소 충돌 방지
location은 호출자 주소와 호출자가 고른 salt로 keccak256(DESIGNATOR ++ address ++ salt)에서 유도됩니다. CREATE2처럼 결정적 주소를 주되, 프리이미지 길이를 55바이트로 달리 해 기존 유도 방식과 충돌을 막습니다. CREATE2의 프리이미지는 85바이트라 길이만으로 충돌이 배제됩니다. CREATE는 RLP([address, nonce])인데, 55바이트가 되려면 논스가 32바이트여야 하고 그 인코딩은 0xf694로 시작해 0xef0100과 다릅니다. 더 작은 논스로 0xef로 시작하는 경우에도 프리이미지가 55바이트보다 짧고 0xef94로 시작하므로 역시 겹치지 않습니다.
EIP-7702 위임 표시자와 같은 객체
SETDELEGATE가 만드는 위임 표시자는 EIP-7702가 만드는 것과 동일한 객체이고 동작도 같습니다. CODESIZE·CODECOPY 처리, 프리컴파일 지정, 위임 연쇄 등 7702에 문서화된 세부 동작이 그대로 적용되고 앞으로 7702 위임 표시자의 동작을 바꾸는 EIP도 여기에 적용되어야 합니다. 이 객체는 컨트랙트가 아니므로 같은 트랜잭션에서 만들어졌더라도 SELFDESTRUCT로 지울 수 없습니다. 삭제는 그것을 만든 호출자가 같은 salt와 0 target으로 SETDELEGATE를 다시 실행하는 방법으로만 가능해야 합니다(SHOULD). 논스를 최소 1로 올리는 9단계는 코드가 지워져도 계정이 EIP-7523이 금지하는 빈 상태로 돌아가지 않게 보장합니다.
보안 고려사항
위임 표시자의 수명 주기 보장은 프로토콜이 아니라 SETDELEGATE를 호출하는 팩토리 컨트랙트가 제공합니다. 이미 쓴 salt의 재실행을 막아 불변으로 만들 수도, 접근 제한된 업그레이드만 허용하고 삭제는 막을 수도 있습니다. 위임 연쇄나 루프는 7702와 마찬가지로 풀어 주지 않으므로, 팩토리가 target 자체에 위임 표시자가 없는지 검사해 방어할 수 있습니다. 초기화 선점 문제는 스마트 컨트랙트가 위임 생성 직후 같은 트랜잭션에서 원자적으로 초기화할 수 있어 7702 서명 방식보다 다루기 쉽습니다. 한 트랜잭션 안에서 같은 salt로 target을 바꿔 가며 여러 번 실행하면 하나의 주소가 여러 코드로 실행되는 상황이 생길 수 있지만 이는 스토리지 슬롯을 바꾸는 기존 업그레이드 프록시에서도 이미 가능한 동작입니다.
활용처와 상태 절감 효과
주요 활용처는 Safe 같은 지갑의 스마트 계정, 엔트리포인트 버전에 맞춰 업그레이드가 필요한 ERC-4337 호환 계정, 그리고 양자내성 계정으로 가는 길에서 EIP-8141 같은 제안이 암묵적으로 요구하는 대량 재배포입니다. 팩토리는 업그레이드 가능형과 불가능형을 모두 배포할 수 있고 일부 계정의 업그레이드만 선택적으로 끌 수도 있어, 업그레이드 로직을 계정 코드에 넣을 필요가 없어집니다. 상태 측면에서는 OpenZeppelin의 ERC-1967 프록시가 약 708바이트인 데 비해 7702 위임은 23바이트에 불과해 상태 사용을 크게 줄이고 호출 전달이 프로토콜 수준으로 내려가면서 ERC-721·ERC-1155 콜백을 포함한 모든 호출의 실행 비용도 줄어듭니다.
진행 상태와 포크 논의
이 EIP는 Draft 상태라 명세가 아직 바뀔 수 있습니다. 콜 기록을 보면 07.30 ACDE #242에서 헤고타(Hegota) 후보로 접수(PFI)되었고 프록시 계정 생성이 조합 가능해지며 약 5배 저렴해진다는 점이 언급되었습니다. 그러나 09.10 ACDE #245에서 EIP-7851(코드 제어 EOA 위임)과 함께 헤고타 후보에서 제외(DFI)되었습니다. 두 EIP 모두 클라이언트 평점이 1.0 미만이었고 옹호하는 이가 없었다는 이유입니다.