작성자: Cobo Global
이더리움(ETH) 메인넷이 곧 Pectra 업그레이드를 맞이하게 되는데, 이는 상당한 규모의 업데이트로 여러 개의 이더리움 개선 제안(Ethereum Improvement Proposals, EIPs)이 한 번에 도입됩니다. 그중 EIP-7702는 이더리움 외부 계정(Externally Owned Account, EOA)에 대한 중대한 개선을 실현했는데, 이 제안은 EOA와 컨트랙트 계정(Contract Account, CA) 간의 경계를 모호하게 만들며 새로운 기능을 제공하여 일반 사용자, 다양한 인프라 제공업체, 개발자 모두에게 큰 영향을 미칠 것입니다.
최근 Pectra가 테스트넷에서 완료되었으며, 곧 메인넷에 배포될 것으로 예상됩니다. 본 문서에서는 EIP-7702의 구현을 심층 분석하고, 이로 인해 발생할 수 있는 기회와 위험을 보여드리며, 다양한 사용자와 실무자들에게 참고 자료를 제공하고자 합니다.
EIP-7702 개요
EIP-7702의 실제 제목은 'EIP-7702: Set EOA account code'이며, 부제는 'Add a new tx type that permanently sets the code for an EOA'입니다. 이는 EOA에 컨트랙트 코드를 설정할 수 있는 새로운 거래 유형을 제공한다는 것을 개략적으로 설명합니다.
구체적으로 말하면, 이 제안은 SET_CODE_TX_TYPE (0x04)이라는 새로운 거래 유형을 도입했으며, 그 데이터 구조는 다음과 같습니다:
rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, value, data, access_list, authorization_list, signature_y_parity, signature_r, signature_s])
authorization_list = [[chain_id, address, nonce, y_parity, r, s], ...]
우리가 일반적으로 알고 있는 0x02 거래 유형과 비교했을 때, 주요 변화는 authorization_list 필드가 추가된 것입니다. authorization_list의 각 요소는 주소 대리 권한 부여를 나타냅니다. 여기에서:
- chain_id는 권한 부여가 적용되는 체인 ID로, 재전송 방지에 사용됩니다.
- nonce는 권한 부여 주소의 nonce로, 일반 거래 nonce와 동일하며 역시 재전송 방지에 사용됩니다.
- address는 주소 대리 시 지정된 대리인입니다.
- y_parity, r, s는 서명 데이터로, ecrecover를 통해 authority 주소, 즉 권한 부여를 시작한 EOA 주소를 얻을 수 있습니다.
각 거래에는 위와 같은 여러 권한 부여가 포함될 수 있습니다. 그리고 이러한 권한 부여에는 독립적인 서명이 필요하며, 본 거래의 서명과 다르기 때문에 주소 권한 부여 행위에 대한 gas 대납이 가능합니다. 지갑 서비스 제공업체나 앱 개발자는 authority의 gas를 지불하여 EOA의 권한 부여를 구현할 수 있으며, authority 자신의 주소에 gas를 보유할 필요가 없습니다.
거래가 블록체인에 기록되면 authority 주소의 code 필드가 대리 주소의 위임 지정(Delegation Designation, DD)으로 설정됩니다. DD의 형식은 다음과 같습니다:
0xef0100 || address
여기서 0xef0100은 고정 접두사이며, address는 대리 대상 주소입니다. 이와 관련하여 주목할 점은 EIP-3541에 따라 사용자가 일반적인 컨트랙트 배포 방식(to 필드가 비어 있는 거래, create/create2 명령)으로 0xef로 시작하는 컨트랙트 코드를 배포할 수 없다는 것입니다. 따라서 위와 같은 위임은 EOA만이 0x04 거래를 통해 수행할 수 있습니다.
위임이 완료되면 authority에 대한 모든 컨트랙트 호출은 address의 code를 사용하고 authority 자체의 storage를 사용하게 됩니다. 이는 ERC-1167 프록시 컨트랙트와 매우 유사한 사용 경험을 제공합니다.
요약하면, EIP-7702는 EOA가 기존의 거래 개시 능력을 유지하면서도 프록시 컨트랙트와 같은 효과를 가질 수 있게 합니다. 사용자는 SET_CODE_TX_TYPE (0x04) 거래를 통해 프록시의 구현 컨트랙트를 설정, 수정, 제거할 수 있습니다.
EIP-7702에 대한 기타 기술적 세부 사항은 제안서 원문을 참고하시기 바랍니다.
EIP-7702가 가져올 영향과 기회
EIP-7702는 중대한 변화로, 블록체인 산업의 모든 참여자에게 큰 영향을 미치며 많은 새로운 기회를 제공합니다.
컨트랙트 지갑 서비스 제공업체
제안서의 제목과 구현 메커니즘을 보면 EIP-7702 자체는 계정 추상화(Account Abstraction, AA)와 관련된 상위 기능(예: gas 추상화, nonce 추상화, 서명 추상화 등)을 특별히 제공하지 않고, 단지 EOA를 프록시 컨트랙트로 전환하는 기본 기능을 제공합니다. 따라서 이 제안은 기존의 다양한 컨트랙트 지갑 인프라(예: Safe, ERC-4337 등)와 충돌하지 않고 거의 seamless하게 통합될 수 있습니다. 사용자의 EOA를 Safe 지갑, ERC-4337 지갑으로 전환할 수 있어, 다중 서명, gas 대납, 일괄 거래, passkey 서명 등 컨트랙트가 제공하는 다양한 기능을 활용할 수 있습니다. 컨트랙트 지갑 제공업체가 EIP-7702를 신속하고 원활하게 통합할 수 있다면 사용자 기반을 확장하고 사용자 경험을 향상시킬 수 있습니다.
DApp 개발자
EIP-7702가 AA 지갑의 사용자 경험을 개선하므로, DApp 개발자는 더 광범위하게 AA 지갑을 채택하여 사용자와 DApp 간의 상호 작용을 더 편리하고 안전하게 제공할 수 있습니다. 예를 들어 컨트랙트 지갑의 일괄 거래 기능을 활용하여 여러 DeFi 작업을 한 번에 수행할 수 있습니다.
또한 DApp은 프로젝트 특성에 따라 사용자 전용 위임 컨트랙트를 개발하여 복잡한 컨트랙트 상호 작용 기능을 제공할 수 있습니다.
자산 보관 기관
거래소, 자금 보관 기관 등은 일반적으로 많은 주소를 관리하여 사용자의 입금 주소로 사용하고 정기적으로 자금을 집계해야 합니다. 기존의 자금 집계 모델에서는 EOA 주소를 입금 주소로 사용하고 집계 시 해당 주소에 일정 금액의 gas를 충전한 후 출금 주소로 전송하는 거래를 수행해야 했습니다. 이 전체 자금 프로세스에는 많은 거래 전송이 포함되어 절차가 길고 상당한 gas 비용이 발생했습니다. 과거에도 기관의 자금 집계로 인해 체인 상의 거래 수수료가 급등하고 거래 정체 현상이 발생한 적이 있습니다.
EIP-7702의 등장으로 EOA 주소를 원활하게 컨트랙트 지갑으로 전환할 수 있으며, EIP-7702의 gas 대납 메커니즘 덕분에 더 이상 gas 충전 거래가 필요하지 않습니다. 또한 컨트랙트 지갑의 프로그래밍 가능성을 활용하여 여러 개의 집계 송금 거래를 단일 거래에 패키징할 수 있어 거래 수를 줄이고 gas 소비를 절감할 수 있습니다. 결과적으로 집계 효율성을 높이고 집계 비용을 낮출 수 있습니다.
EIP-7702가 가져올 잠재적 위험
EIP-7702는 새로운 계정 기능을 도입하지만 동시에 잠재적인 보안 위험도 수반합니다. 지갑 서비스 제공업체, 컨트랙트 개발자, 사용자 모두 주의를 기울여야 합니다.
지갑 서비스 제공업체
EIP-7702는 새로운 거래 유형인 SET_CODE_TX_TYPE (0x04)를 도입했는데, 이 거래 유형은 일반 사용자와도 직접 관련됩니다. 따라서 Metamask, Rabby 등의 소프트웨어 지갑 서비스와 하드웨어 지갑 서비스 모두 새로운 거래 유형을 지원하도록 소프트웨어를 업데이트해야 합니다.
EIP-7702의 권한 부여에는 전체 계정을 장악할 수 있는 가능성이 있으므로, 지갑 서비스 제공업체는 UI에서 사용자에게 충분한 경고와 알림을 제공해야 합니다. 이는 Token Approve, Permit과 동등하거나 더 높은 수준의 경고 수준이 필요합니다.
새로운 거래 유형을 연계하고 사용자 상호 작용을 설계할 때 보안 검사가 충분하지 않으면 피싱 공격에 노출될 수 있습니다.
일반 사용자
일반 사용자 역시 이더리움의 새로운 거래 유형에 주목하고 각종 소프트웨어 지갑과 하드웨어 지갑의 업데이트 상황을 주시해야 합니다. 새로운 특수 거래 유형을 효과적으로 식별하고 충분한 주의를 기울여야 합니다.
이 거래 유형의 경우 위임 대상 컨트랙트를 주의 깊게 확인해야 하며, 기술적 역량이 있다면 컨트랙트 소스 코드에 대한 감사를 수행하여 보안 위험을 방지해야 합니다. 일반 사용자는 권한 부여 대상 컨트랙트가 오픈소스이며 신뢰할 수 있는 제3자 감사 보고서를 제공하는지 확인해야 합니다.
새로운 거래 유형은 이전의 거래 유형보다 감사하기 어렵고 지갑에 대한 더 강력한 통제 기능
하지만 EIP-7702 시나리오에서 권한 서명은 authorization_list에 독립적으로 존재하므로, 선점 봇은 메모리 풀에서 권한 거래를 모니터링하고 권한 거래를 먼저 전송하여 초기화 함수를 호출함으로써 계약 지갑의 권한을 선점할 수 있습니다. EOA 지갑에 암호화 자산이 이미 있는 경우 선점 과정에서 자산 이체가 직접 발생할 수 있어 사용자에게 자금 손실을 초래할 수 있습니다. 업그레이드가 완료된 직후 일정 기간 동안 EIP-7702 초기화 선점 공격이 체인상에 발생할 것으로 추측할 수 있습니다.
조사 결과, 기존 Proxy 모델의 대부분의 코드 구현은 EIP-7702 시나리오에서 안전하게 초기화될 수 없습니다. 개발자는 기존 코드를 EIP-7702에 맞게 적응시킨 후에 사용자에게 공개해야 합니다. 사용자 또한 다양한 이전 버전의 계약에 권한을 부여하지 않도록 주의하여 자금 안전을 보장해야 합니다.
개발자 입장에서 EIP-7702 적응은 주로 초기화 방법에 대한 권한 검증입니다. 일반적인 검증 코드는 다음과 같습니다:
require(msg.sender == address(this), "Only self")
또는
require(ECDSA.recover(hash, signature) == address(this), "Only signed")
이를 통해 EOA 자체 또는 유효한 서명을 가진 경우에만 초기화 방법을 호출할 수 있도록 보장합니다. Gas 대납 시나리오를 고려할 때 후자가 더 일반적으로 사용될 수 있습니다.
2. Delegation 계약의 저장 구조 충돌 문제
EIP-7702 시나리오에서 EOA는 Delegation 업데이트를 자주 수행할 수 있는데, 이는 Proxy 업그레이드와 유사합니다. 각 Delegation 계약은 다른 지갑 공급업체 및 DApp 개발자가 제공할 수 있으므로 구현이 서로 다를 수 있습니다. 단일 개발자 시나리오의 계약 업그레이드와 달리 호환성을 보장하기 어렵습니다.
다른 Delegation 계약의 변수 저장 구조는 대부분 완전히 다를 것입니다. 만약 계약 간에 동일한 Storage slot을 사용한다면 잘못된 데이터를 읽거나 예상치 못한 데이터를 쓰게 되어 계약 기능이 비정상적일 수 있습니다. 데이터 오류가 발생하면 수정하는 것도 매우 어려운 기술이 필요하므로 일반 사용자가 처리하기 어렵습니다.
이에 개발자는 ERC-7201의 Storage 관리 모델을 사용하여 Namespace 방식으로 독립적인 Storage 공간을 사용하는 것이 좋습니다.
3. Delegation 권한 관리 문제
EIP-7702는 Proxy 계약과 매우 유사하지만, 이더리움 프로토콜 수준에서 implementation 계약 관리가 이루어집니다. 즉, Proxy에는 고정되고 변경 불가능한 owner가 있습니다. 따라서 EOA 계정은 언제든 계약을 업데이트하고 Storage 공간의 모든 데이터를 수정하며 임의의 작업을 수행할 수 있습니다.
개발자는 이러한 차이점에 주목해야 하며, DApp 개발 시 EOA Storage 공간의 데이터를 신뢰할 수 없습니다. 특히 Solana, SUI 사용자 모델에 익숙한 개발자는 이 문제에 더 주의해야 합니다. 일반 사용자 또한 이 문제에 유의해야 합니다.
예를 들어 EOA를 다중 서명 지갑에 위임한 경우에도 최고 권한은 여전히 EOA 개인 키에 있습니다.
4. 새로운 EOA가 기존 보안 가정을 깨는 문제
이전 버전 계약에는 호출자가 EOA라는 보안 가정에 의존하는 경우가 있는데, 이것이 깨질 수 있습니다. 일반적으로 다음과 같은 코드로 호출자가 EOA인지 확인합니다:
require(msg.sender == tx.origin, "Only EOA")
더 나아가 EOA가 계약 호출 기능이 없고 일괄 호출을 하지 않을 것이라는 가정에 따라 일부 제한 또는 재진입 검사 로직을 수행하기도 합니다.
EIP-7702 시나리오에서 EOA와 CA의 경계가 모호해지며, EOA도 코드 실행 기능을 가지게 됩니다. 위의 검사를 통과하더라도 EOA Proxy 계약의 fallback이 트리거되어 재진입 문제가 발생할 수 있습니다. 또한 일부 메서드(예: 토큰 마이닝 배포, NFT 민팅 등)가 거래당 한 번만 호출할 수 있도록 제한되어 있는데, EOA Proxy를 통해 이를 우회하여 개발자가 예상하지 못한 방식으로 이익을 취할 수 있습니다.
참고 자료
[1] EIP-3541: https://eips.ethereum.org/EIPS/eip-3541
[2] ERC-1167: https://eips.ethereum.org/EIPS/eip-1167
[3] EIP-7702: https://eips.ethereum.org/EIPS/eip-7702
[4] ERC-4337 SimpleAccount: https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/accounts/SimpleAccount.sol
[5] ERC-7201: https://eips.ethereum.org/EIPS/eip-7201