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 미만의 작은 코드입니다. 클론과 프록시가 그 상당수를 차지할 가능성이 높아, 이 역할을 프로토콜 차원에서 더 작고 싸게 처리할 방법이 필요합니다.

무엇이 바뀌나

지금

EIP-7819 이후

누구에게 영향이 있나

심층 설명

명령어 동작 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 미만이었고 옹호하는 이가 없었다는 이유입니다.

EIP 원문 · ← EIPs