EIP-7851 코드 제어 EOA 위임 (Code-Controlled EOA Delegation)
Hegota 포함 제외 (DFI) · 계정 추상화 · 원문 상태 Draft · 2024-12-27 작성
EIP-7702로 위임된 EOA가 지갑 코드로 직접 위임 대상을 바꾸고 원래 개인키(ECDSA)의 권한을 영구히 끌 수 있게 합니다. 새 위임 접두사 0xef0101과 SETSELFDELEGATE 명령어를 추가합니다.
왜 필요한가
EIP-7702는 일반 계정(EOA)이 스마트 계약처럼 동작하도록 위임을 걸 때 원래 개인키의 서명(ECDSA)으로 시작합니다. 그런데 일단 통제가 지갑 코드로 넘어가면, 사용자는 패스키나 멀티시그, 소셜 리커버리 같은 지갑 코드 쪽 수단으로 계정을 운영하게 됩니다. 그 뒤에도 원래 개인키는 살아 있어서 여전히 트랜잭션을 서명하거나 위임을 마음대로 바꿀 수 있는 잔여 권한으로 남는다는 문제가 있습니다. 또 현재 구조에서는 위임을 바꾸려면 다시 원래 키의 서명이 필요해서 지갑 코드가 위임의 수명주기를 스스로 관리할 수 없습니다. 이 EIP는 지갑 코드가 위임을 직접 갱신할 수 있게 하고 원래 키의 잔여 권한을 영구히 소각(비활성화)하는 길을 엽니다.
무엇이 바뀌나
지금
- 위임의 시작과 변경 모두 원래 EOA 개인키의 ECDSA 서명으로만 승인합니다.
- 패스키나 멀티시그로 계정을 운영해도 원래 개인키의 권한이 그대로 남아 있습니다.
- 남아 있는 원래 키 권한을 끌 방법이 없습니다.
EIP-7851 이후
- 지갑 코드가 SETSELFDELEGATE 명령어로 자기 계정의 위임 대상을 직접 바꿉니다.
- 첫 호출에서 계정 코드가 0xef0101 접두사로 바뀌며 원래 키의 ECDSA 권한이 영구히 꺼집니다.
- 권한이 꺼진 뒤에도 지갑 코드로는 위임을 계속 갱신할 수 있습니다.
누구에게 영향이 있나
- 사용자: 패스키, 멀티시그, 소셜 리커버리 같은 지갑 코드 쪽 수단만으로 계정을 운영하면서 원래 개인키의 잔여 권한을 소각할 수 있습니다. 단 한 번 끄면 되돌릴 수 없습니다.
- 지갑 개발자: SETSELFDELEGATE는 명시적인 사용자 확인을 받은 뒤에만 노출하고 최고 권한 작업으로 다뤄야 합니다.
- 클라이언트 팀: 0xef0101 코드를 실행 단계에서는 0xef0100과 똑같은 위임으로, 검증 단계에서는 ECDSA 비활성 표시로 인식하도록 구현해야 합니다.
- 노드 운영자(트랜잭션 풀): 보낸 계정의 코드가 0xef0101로 시작하면 ECDSA 서명 트랜잭션을 거부해야 하므로, 발신자 계정 코드를 한 번 더 읽는 작업이 추가될 수 있습니다.
심층 설명
두 가지 위임 접두사: 0xef0100과 0xef0101
EIP-7702의 기존 위임 지시자는 0xef0100 || delegate_address이고, 이 EIP가 추가하는 0xef0101 || delegate_address는 ECDSA 비활성 위임입니다. ECDSA 비활성이란 원래 ECDSA 키가 트랜잭션이나 EIP-7702 위임 변경을 더는 승인할 수 없다는 뜻이며 위임 대상이 영원히 동결된다는 뜻은 아닙니다. 지갑 코드는 ECDSA 비활성 상태를 유지한 채 위임 대상을 갱신할 수 있습니다. 비가역 불변식은 하나입니다. ECDSA 권한은 한 번 꺼지면 절대 복원되지 않습니다. 위임 코드 실행에서는 클라이언트가 0xef0101을 0xef0100과 동일하게 다뤄야 하므로, 실행 경로 자체는 달라지지 않습니다.
SETSELFDELEGATE 명령어 동작
SETSELFDELEGATE(delegate_address)는 자기 계정 전용(self-only)입니다. authority는 현재 실행 컨텍스트 주소로 정의되고 이 명령어는 authority만 갱신합니다. 스택에서 항목 하나를 받아 하위 160비트를 delegate_address로 해석하고 성공 시 1, 상태 변경이 없으면 0을 올립니다. 실행 로직은 세 단계입니다. 첫째, delegate_address가 address(0)이면 0을 올리고 상태를 바꾸지 않습니다. 둘째, authority의 상태에 저장된 원시 코드(현재 프레임의 위임 지시자를 따라간 코드가 아님)가 정확히 23바이트이고 0xef0100 또는 0xef0101로 시작하면 code(authority)를 0xef0101 || delegate_address로 쓰고 1을 올립니다. 셋째, 그 외에는 0을 올립니다. 가스는 시도마다 SETSELFDELEGATE_GAS(9500)를 소모하고 정적 컨텍스트에서 실행되면 예외 중단해야 합니다. 상태 변경은 일반 EVM revert 의미론을 따라 프레임이나 트랜잭션이 revert되면 함께 되돌아갑니다. 명령어 코드값(SETSELFDELEGATE_OPCODE)은 아직 TBD입니다.
갱신 효과는 프레임 단위로 적용
성공적으로 갱신된 뒤에는 authority를 대상으로 하는 이후의 코드 실행 연산이 갱신된 위임 지시자를 따라 실행할 코드를 얻습니다. 효과는 프레임 로컬입니다. 이미 코드를 얻어 실행 중인 프레임은 그 코드를 계속 실행하고 같은 트랜잭션 안에서 나중에 authority를 다시 호출(재진입)하면 그 호출은 이후의 코드 실행 연산이므로 갱신된 위임 지시자로 코드를 불러옵니다. 또한 ECDSA 활성 위임(0xef0100)에서 호출하면 ECDSA 권한을 끄면서 위임을 설정하고 이미 비활성(0xef0101)인 위임에서 호출하면 비활성 상태를 유지한 채 재위임합니다.
검증 규칙: 비활성 계정의 서명 차단
EIP-7702 승인 처리 중에 authority의 현재 코드가 정확히 23바이트이고 0xef0101로 시작하면, 그 authority가 서명한 승인은 모두 무효로 보고 건너뜁니다. 또 복구된 발신자의 코드가 현재 상태에서 정확히 23바이트이고 0xef0101로 시작하는 ECDSA 인증 트랜잭션은 무효이며 블록에 포함될 수 없습니다. 트랜잭션 풀도 이런 트랜잭션을 거부해야 합니다. 실행 부하 변화는 작습니다. 위임 코드를 이미 해석하는 실행 경로는 기존 위임 코드 조회를 재사용할 수 있고 트랜잭션 풀은 발신자 계정 코드 읽기가 한 번 추가될 수 있습니다.
가스 9500의 근거
SETSELFDELEGATE_GAS는 9500으로, EIP-7702의 PER_AUTH_BASE_COST에서 authority 주소 복구에 할당된 3000 가스를 뺀 값과 같습니다. 이 명령어는 위임이 이미 해석된 뒤 현재 실행 컨텍스트 계정에 23바이트 위임 지시자 하나를 쓸 뿐, 서명을 검증하지 않고 승인 튜플을 처리하지 않으며 계정 논스를 올리거나 다른 계정을 건드리지도 않기 때문입니다.
보안 범위: 프로토콜 서명만 막고 컨트랙트 서명 검증은 못 막음
이 EIP가 무효화하는 것은 프로토콜 수준의 ECDSA 인증 트랜잭션과 EIP-7702 승인뿐입니다. 토큰의 permit 함수처럼 컨트랙트가 직접 ECDSA 서명을 검증하는 경우에는 ECDSA 비활성 계정의 서명이 자동으로 거부되지 않습니다. ecrecover 프리컴파일이 ECDSA 비활성 계정을 어떻게 다룰지는 동반 제안인 EIP-8151에서 다룹니다. 또 ECDSA 비활성 진입은 비가역이므로, 지갑은 SETSELFDELEGATE를 명시적인 사용자 확인 뒤에만 노출하고 최고 권한으로 취급해야 합니다. 기존 0xef0100 위임은 그대로 유지되어 하위 호환성 문제는 없습니다.
진행 상태: Draft, 헤고타 후보에서는 제외
이 EIP는 Draft 상태라서 명세가 아직 바뀔 수 있고 명령어 코드값도 TBD입니다. 2026년 9월 10일 ACDE #245 콜에서 EIP-7819(set delegate 명령어)와 함께 헤고타(Hegota) 포크 후보에서 제외(DFI)되었습니다. 두 EIP 모두 클라이언트 평점이 1.0 미만이었고 옹호하는 이가 없었습니다.