~/blockchain-dev.md
BLOCKCHAIN_DEV

EIP-7702 지갑은 왜 “업그레이드”보다 “권한 위임”으로 봐야 할까

10분 읽기·2026.06.24·출처 5·00
오늘의 질문

EOA가 코드 포인터를 가질 수 있게 되면, 지갑·dApp·컨트랙트 개발자는 어떤 오래된 보안 가정을 버려야 할까?

blockchain-dev.md
SURVIVE.exe

EIP-7702 지갑은 왜 “업그레이드”보다 “권한 위임”으로 봐야 할까

1. 왜 지금 봐야 하나

Ethereum Pectra 이후 EIP-7702는 “기존 EOA를 스마트 계정처럼 쓸 수 있게 해준다”는 장점으로 설명되는 경우가 많다. 같은 주소를 유지하면서 batching, gas sponsorship, session key, permissioned subkey 같은 기능을 붙일 수 있으니 UX 측면에서는 매우 매력적이다. Ethereum Foundation의 Pectra mainnet announcement도 EIP-7702를 “widespread account abstraction”으로 가는 큰 단계라고 설명했다.

하지만 개발자 관점에서 더 중요한 문장은 “EOA가 편해졌다”가 아니다. EOA가 실행 로직을 다른 컨트랙트 주소에 위임할 수 있는 계정이 되었다는 점이다. ethereum.org의 7702 가이드는 authorization tuple이 [chain_id, address, nonce, y_parity, r, s] 형태이고, delegate target인 address의 코드가 EOA의 실행 로직처럼 쓰인다고 설명한다. EIP 본문은 이 결과를 0xef0100 || address delegation indicator로 표현한다.

이 변화는 지갑 개발자만의 문제가 아니다. dApp이 “tx.origin은 사람이 가진 EOA다”, 컨트랙트가 “msg.sender.code.length == 0이면 단순 EOA다”, 백엔드가 “한 번의 서명은 한 번의 행동만 허용한다”고 가정했다면, 7702 이후에는 그 전제가 흔들린다.

오늘 가져갈 한 문장은 이것이다.

EIP-7702는 EOA에 기능을 더하는 업그레이드가 아니라, 계정의 실행 권한을 코드 포인터에 맡기는 새로운 권한 경계다.

2. 핵심 개념

EIP-7702는 새로운 transaction type 0x04, 흔히 set-code transaction을 도입한다. 이 transaction에는 authorization list가 들어간다. 각 authorization tuple은 다음 정보를 담는다.

zsh — 생존확인.sh
[chain_id, address, nonce, y_parity, r, s]

여기서 address는 EOA가 실행을 위임할 이미 배포된 컨트랙트 주소다. EIP는 유효한 tuple을 처리할 때 authorizing account의 코드 위치에 다음 delegation indicator를 쓴다.

zsh — 생존확인.sh
0xef0100 || address

이후 EOA를 대상으로 하는 code executing operation은 이 indicator가 가리키는 컨트랙트 코드를 로드해 실행한다. 중요한 점은 그 코드가 EOA의 context에서 동작한다는 것이다. 주소, 잔고, storage 관점에서 사용자는 같은 EOA를 쓰는 것처럼 보이지만, 실행 규칙은 delegate contract가 정한다.

이 구조가 주는 편익은 명확하다.

  • 여러 호출을 한 번에 묶는 batching
  • 다른 주체가 gas를 대납하는 sponsorship
  • 제한된 권한을 가진 session key 또는 subkey
  • ERC-4337 bundler/paymaster와의 결합
  • 기존 주소와 자산을 유지한 점진적 account abstraction

하지만 같은 메커니즘은 보안 질문도 만든다.

첫째, 위임은 단일 호출 권한이 아니라 계정 실행 방식의 변경이다. 사용자가 악성 delegate address에 서명하면, 이후 그 EOA로 들어오는 호출이 공격자 코드로 라우팅될 수 있다.

둘째, authorization tuple에는 chain_id가 있다. EIP와 ethereum.org 가이드는 chain_id = 0이면 모든 chain id에 적용되는 authorization이 될 수 있다고 설명한다. 같은 주소에 같은 코드가 배포된다는 보장이 없다면, 한 체인에서 의도한 위임이 다른 EVM 체인에서 전혀 다른 코드 권한이 될 수 있다.

셋째, delegation transaction 자체는 constructor/initcode를 실행하지 않는다. EIP 본문은 이 때문에 지갑 개발자가 initialization front-running을 고려해야 한다고 말한다. 위임 후 별도 transaction으로 initialize()를 호출하는 구조라면, 관찰자가 먼저 초기화 값을 넣어 계정 설정을 빼앗을 수 있다.

3. 최신 이슈와 연결

ethereum.org의 2026년 6월 업데이트된 7702 가이드는 보안 권고를 꽤 직접적으로 쓴다. 대표적으로 다음 세 가지다.

  1. dApp이 직접 7702 authorization signature를 요구한다고 가정하지 말고, wallet_sendCalls 같은 지갑 인터페이스 또는 ERC-4337/모듈형 계정 흐름을 사용하라.
  2. delegate target은 immutable contract를 선호하고, proxy나 metamorphic contract처럼 나중에 의미가 바뀔 수 있는 대상을 조심하라.
  3. chain_id = 0 authorization은 모든 EVM 체인에 영향을 줄 수 있으므로, 정말 동일한 코드와 동일한 의미가 보장될 때만 사용하라.

arXiv의 “EIP-7702 Phishing Attack” 논문은 이 문제를 phishing primitive로 해석한다. 전통적인 피싱은 사용자가 악성 transaction, approval, permit, NFT approval을 서명하도록 속이는 방식이었다. 7702에서는 사용자가 단 하나의 authorization tuple에 서명하면, 이후 계정의 실행 로직이 공격자 코드로 바뀔 수 있다. 논문은 이 차이를 “transaction-level deception”에서 “account-level execution hijacking”으로의 이동이라고 설명한다.

Openfort의 2026년 글도 실무 통합 관점에서 같은 결론을 낸다. 7702는 ERC-4337을 대체하는 것이 아니라, “7702가 계정을 업그레이드하고 4337이 bundler/paymaster와 상호작용하는 방식을 표준화한다”는 관계다. 즉 제품팀이 7702를 붙일 때는 set-code transaction만 보면 안 되고, 지갑 UI, delegate registry, bundler, paymaster, dApp capability detection까지 하나의 표면으로 봐야 한다.

4. 개발자 관점 해석

dApp 개발자: “EOA만 허용” 가정이 깨진다

많은 컨트랙트와 백엔드는 EOA와 contract wallet을 구분하려고 했다. 예를 들어 tx.origin == msg.sender, msg.sender.code.length == 0, signature만 있으면 사람이 승인했다고 보는 흐름이다. 7702 이후에는 EOA 주소가 그대로 유지되면서도 실행은 delegate code를 따를 수 있다. 따라서 “EOA 주소인가?”보다 중요한 질문은 “이 계정이 현재 어떤 delegate behavior를 갖고 있는가?”다.

실무적으로는 다음을 점검해야 한다.

  • EOA-only gating을 보안 경계로 쓰고 있지 않은가?
  • sponsor, relayer, bundler가 calldata/value/gas/target을 바꿔도 서명 검증이 막는가?
  • capability detection 없이 7702 기능을 assume하고 있지 않은가?

지갑 개발자: 서명 UI는 calldata가 아니라 delegate 의미를 보여줘야 한다

7702 authorization은 짧은 tuple이다. 사용자에게 숫자와 주소만 보여주면 충분하지 않다. 실제로는 그 주소의 코드가 계정의 실행 권한을 갖는다. 지갑 UI는 최소한 다음을 보여줘야 한다.

  • delegate contract 주소와 검증 상태
  • source/audit/known implementation 여부
  • chain-specific authorization인지, chain_id = 0인지
  • 이 위임이 revoke될 때까지 지속되는지
  • 해당 delegate가 batch, spending, session key, paymaster 권한을 어떻게 처리하는지

즉 “서명하시겠습니까?”가 아니라 “이 계정의 실행 방식을 이 코드로 바꾸시겠습니까?”라고 물어야 한다.

스마트 계정 구현자: initialize는 별도 버튼이 아니다

EIP-7702는 initcode를 실행하지 않는다. 그러면 delegate contract가 EOA storage에 필요한 설정을 쓰려면 initialization call이 필요하다. 위험한 패턴은 다음과 같다.

zsh — 생존확인.sh
1. 사용자가 EOA를 SmartAccount7702로 delegate한다.
2. 다음 transaction에서 initialize(owner, entryPoint, policy)를 호출한다.
3. mempool 관찰자가 먼저 initialize(attacker, attackerEntryPoint, policy)를 호출한다.

EIP 본문과 ethereum.org 가이드는 setup calldata가 EOA key로 서명되었는지 검증하거나, ERC-4337 EntryPoint를 통해서만 초기화되게 하는 식의 대응을 제안한다. 더 단순히 말하면, initialize()는 누구나 호출 가능한 함수가 아니라 EOA가 승인한 초기 상태만 받아들이는 상태 전이여야 한다.

5. 내 프로젝트에 적용할 체크포인트

  • tx.origin == msg.sender 또는 code.length == 0을 접근 제어로 쓰는 곳이 있는가?
  • 지갑 연결 후 “EOA니까 안전하다”는 문구나 로직이 있는가?
  • 서명 검증 메시지가 target, calldata, value, nonce, chain_id, gas limit 중 일부를 빠뜨리지 않는가?
  • 7702 authorization을 직접 요구하는 dApp 흐름이 있다면, 표준 wallet interface로 대체할 수 있는가?
  • delegate implementation allowlist가 주소만 보나, source/audit/bytecode/CREATE2 배포 조건까지 보나?
  • chain_id = 0 authorization을 기본값으로 쓰고 있지 않은가?
  • proxy delegate, upgradeable delegate, metamorphic deployment를 허용하고 있지 않은가?
  • initialization이 별도 transaction이면 front-running 테스트가 있는가?
  • revoke, replace delegation UX와 비상 차단 절차가 있는가?
  • backend risk engine이 7702 delegation indicator 0xef0100 || address를 감지할 수 있는가?

6. 오늘 10분 액션

  1. 코드베이스에서 tx.origin, code.length, isContract, “EOA only”를 검색한다.
  2. 사용자 서명 메시지에 chain_id, nonce, target, calldata, value가 모두 포함되는지 하나만 골라 확인한다.
  3. 지갑 또는 계정 추상화 기능을 만든다면 “delegate allowlist” 표를 만든다: address, chain, bytecode hash, audit link, upgradeability 여부, revoke 방법.
  4. 테스트에 “악성 delegate address”, “chain_id=0”, “initialize frontrun” 세 케이스를 추가할 수 있는지 이슈를 연다.

7. 더 볼 자료

중복 회피 메모

최근 blockchain_dev 글은 Syscoin bridge cross-layer parsing, Axelar-Secret IBC source channel 인증, EIP-7732 ePBS, EIP-7918 blob fee reserve, Chainlink CCIP TokenPool upgrade, Aztec Connect L1/L2 settlement mismatch, OP Stack interop, ProxyAdmin 권한 사고를 다뤘다. 과거 account abstraction 글이 있었다면 주로 native AA의 기능·delegation/revoke 개념에 가까웠고, 이번 글은 2026년 업데이트된 ethereum.org 7702 가이드와 EIP 본문·피싱 연구를 바탕으로 delegate target, chain_id=0, initialization front-running, EOA-only assumption 붕괴라는 보안 경계에 집중해 중복을 피했다.

오늘 10분 액션+5%

댓글 0

최신순 ▾
한 줄 남기기

혹시 이 글을 읽는 동료 개발자가 있다면, GitHub으로 로그인하고 한 줄 흔적을 남겨줘요. (스팸 방지용 로그인이에요)