이더리움 Pectra 업그레이드: EIP-7702 실용 가이드
저자:Cobo Global
이더리움 메인넷에 곧 도래할 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에 계약 코드를 설정할 수 있는 거래 유형을 제공합니다.
구체적으로, 이번 제안은 SETCODETX_TYPE (0x04) 거래 유형을 도입하며, 그 데이터 구조는 다음과 같습니다:
rlp([chainid, nonce, maxpriorityfeepergas, maxfeepergas, gaslimit, destination, value, data, accesslist, authorizationlist, signatureyparity, signaturer, signature_s])
authorizationlist = [[chainid, address, nonce, y_parity, r, s], …]
우리가 일반적으로 접하는 0x02 거래 유형과 비교할 때, 주요 변화는 authorizationlist 필드가 추가된 것입니다. authorizationlist의 각 요소는 주소 대리 권한을 부여하는 것을 나타냅니다. 여기서:
- chain_id는 권한이 유효한 체인 ID로, 재전송 방지를 위해 사용됩니다.
- nonce는 권한 부여자의 주소의 nonce로, 일반 거래 nonce와 일치하며 재전송 방지를 위해 사용됩니다.
- address는 주소 대리 시 지정된 대리인입니다.
- y_parity, r, s는 서명 데이터로, ecrecover를 통해 authority 주소, 즉 권한을 부여한 EOA 주소를 얻을 수 있습니다.
각 거래에는 위의 권한이 여러 개 포함될 수 있습니다. 또한 위의 권한은 본체 거래의 서명과는 별도의 서명이 필요하므로 주소 권한 부여 행동에 대한 가스 대납이 가능합니다. 지갑 서비스 제공자나 앱 개발자는 authority의 가스를 지불하여 EOA의 권한을 부여할 수 있으며, authority 자체 주소에 가스를 저장할 필요가 없습니다.
거래가 블록체인에 올라가면 authority 주소의 code 필드는 대리 주소에 대한 위임 식별(Delegation Designation, DD)으로 설정됩니다. DD의 형식은 다음과 같습니다:
0xef0100 || address
여기서 0xef0100은 고정 접두사이며, address는 대리의 목표 주소입니다. 여기서 한 가지 세부 사항은 EIP-3541에 따라 사용자는 일반적인 계약 배포 수단(목적지가 비어 있는 거래, create/create2 명령)을 통해 0xef로 시작하는 계약 코드를 배포할 수 없다는 것입니다. 따라서 위의 위임은 EOA만이 발동할 수 있으며, 0x04 거래를 통해 완료됩니다.
위임이 완료되면, authority에 대한 모든 계약 호출은 address의 코드를 code로 사용하고, 동시에 authority 자체의 storage를 사용합니다. 사용 경험은 ERC-1167 프록시 계약과 매우 유사합니다.
요약: EIP-7702는 EOA가 원래 거래 발동 능력을 유지하면서도 프록시 계약의 효과를 갖추게 합니다. 사용자는 SETCODETX_TYPE (0x04) 거래를 통해 프록시의 Implementation 계약을 설정, 수정 및 제거할 수 있습니다.
EIP-7702에 대한 기타 기술적 세부 사항은 제안 원문을 참조하시기 바랍니다.
EIP-7702가 가져오는 영향과 기회
EIP-7702는 중대한 변화로, 블록체인 산업의 모든 참여자에게 중대한 영향을 미치며, 많은 새로운 기회를 제공합니다.
계약 지갑 서비스 제공자
제안 자체의 제목과 구현 메커니즘에서 볼 수 있듯이, EIP-7702는 계좌 추상화(Account Abstraction, AA)에 대한 상위 기능(예: 가스 추상화, nonce 추상화, 서명 추상화 등)을 특별히 제공하지 않으며, 단지 EOA를 프록시 계약으로 변환할 수 있는 기본 기능을 제공합니다. 따라서 이 제안은 현재의 다양한 계약 지갑 인프라(예: Safe, ERC-4337 등)와 충돌하지 않습니다. 반대로, EIP-7702는 기존의 계약 지갑과 거의 원활하게 통합될 수 있습니다. 사용자의 EOA가 Safe 지갑, ERC-4337 지갑으로 변환될 수 있습니다. 이를 통해 계약이 제공하는 다중 서명, 가스 대납, 배치 거래, 패스키 서명 등의 기능을 통합할 수 있습니다. 계약 지갑 제공자가 EIP-7702를 신속하고 원활하게 통합할 수 있다면, 사용자 집단을 효과적으로 확장하고 사용자 경험을 향상시킬 수 있습니다.
DApp 개발자
EIP-7702가 AA 지갑의 사용자 경험을 향상시켰기 때문에, DApp 개발자는 AA 지갑을 더 넓은 범위로 통합하여 사용자와 DApp 간의 상호작용을 보다 편리하고 안전하게 제공할 수 있습니다. 예를 들어, 계약 지갑의 배치 거래 기능을 활용하여 여러 DeFi 작업을 한 번에 완료할 수 있습니다.
또 다른 방향으로 DApp은 프로젝트 특성에 따라 사용자 맞춤형 Delegation 계약을 개발하여 사용자에게 전용의 복잡한 계약 상호작용 기능을 제공할 수 있습니다.
자산 관리자
거래소 및 자산 관리자는 일반적으로 많은 주소를 관리하여 사용자 충전 주소로 사용하고, 정기적으로 자금을 집계해야 합니다. 전통적인 자금 집계 모델에서는 EOA 주소를 충전 주소로 사용하며, 집계 시 충전 주소에 일정 금액의 가스를 충전해야 하고, 충전 주소에서 출금 주소로 송금 거래를 수행해야 합니다. 전체 자금 과정은 많은 거래 전송을 포함하며, 절차가 길고 높은 가스 비용을 지불해야 합니다. 역사적으로 기관이 자금을 집계하여 체인 상 거래 비용이 상승하고 거래가 혼잡해지는 경우도 있었습니다.
EIP-7702의 출현은 EOA 주소를 원활하게 계약 지갑으로 변환할 수 있으며, EIP-7702의 가스 대납 메커니즘 덕분에 가스 충전 거래가 더 이상 필요하지 않습니다. 또한 계약 지갑의 프로그래머블성을 활용하여 여러 집계 송금을 단일 거래로 패키징하여 거래 수를 줄이고 가스 소비를 절약할 수 있습니다. 궁극적으로 집계 효율성을 높이고 집계 비용을 줄일 수 있습니다.
EIP-7702가 가져오는 잠재적 위험
EIP-7702는 새로운 계좌 기능을 가져오는 동시에 잠재적인 보안 위험도 도입하므로, 지갑 서비스 제공자, 계약 개발자, 사용자는 경계를 유지해야 합니다.
지갑 서비스 제공자
EIP-7702는 새로운 거래 유형 SETCODETX_TYPE (0x04)을 도입했으며, 이 거래 유형은 일반 사용자와 직접 관련이 있습니다. 따라서 Metamask, Rabby 등 소프트웨어 지갑 서비스 제공자와 다양한 하드웨어 지갑 서비스도 새로운 거래 유형에 적응하기 위해 소프트웨어를 업데이트해야 합니다.
EIP-7702의 권한 부여는 전체 계정을 인수할 가능성이 있으므로, 지갑 서비스 제공자는 UI에서 사용자에게 충분한 경고를 제공해야 하며, 경고 수준은 Token Approve, Permit과 동등하거나 그 이상이어야 합니다.
새로운 거래 유형에 대한 연동 및 사용자 상호작용에서 보안 검사가 충분히 엄격하지 않으면 사용자가 피싱 공격을 받을 수 있습니다.
일반 사용자
일반 사용자도 이더리움의 새로운 거래 유형에 주의를 기울이고, 각종 소프트웨어 지갑 및 하드웨어 지갑의 업데이트를 주의 깊게 살펴봐야 합니다. 새로운 특수 거래 유형을 효과적으로 인식하고 충분한 주의를 기울여야 합니다.
이 거래 유형은 Delegation의 목표 계약을 중점적으로 검증해야 하며, 기술적 준비가 되어 있다면 계약 소스 코드를 감사하여 보안 위험을 피하는 것이 좋습니다. 일반 사용자는 권한 부여된 계약이 오픈 소스인지, 제3자가 신뢰할 수 있는 감사 보고서를 제공하는지 주의해야 합니다.
새로운 거래 유형은 이전 거래 유형보다 감사하기 더 어렵고, 지갑에 대한 제어 능력이 더 강합니다. 앞으로 이 거래 유형을 사용하는 피싱 공격이 발생할 것이라고 예상할 수 있습니다. 일반 사용자는 관련 지식을 적극적으로 쌓고, 보안 인식을 높여야 합니다.
계약 개발자
계약 개발자에게 EIP-7702는 새로운 관점을 제공합니다. Delegation 계약에 대한 성숙한 공개 라이브러리 구성 요소나 개발 표준이 없기 때문에, 업그레이드 초기에는 개발자들이 각자 자신의 Delegation 계약을 구현해야 할 가능성이 높습니다. 개발자는 새로운 기능이 도입하는 보안 위험을 피하기 위해 충분한 조사를 수행하는 것이 좋습니다.
Cobo 보안 팀의 분석에 따르면, EIP-7702에서 계약 보안에 주의해야 할 내용은 다음과 같습니다:
1. Delegation 계약의 초기화 경쟁 문제
EIP-7702는 set code의 기능만 제공하며, 계약 초기화 기능은 제공하지 않습니다. 개발자가 익숙한 Proxy 메커니즘과 비교할 때, EIP-7702는 implementation을 업데이트하는 능력을 제공하지만, initialize 함수를 호출하는 능력은 제공하지 않습니다.
현재 존재하는 다양한 주류 계약 지갑의 예를 들면, ERC-4337 공식 구현의 지갑은 initialize 메서드를 제공하며, initialize 메서드에는 권한 검사가 없습니다. 이 메서드를 처음 호출한 사용자가 지갑의 모든 권한을 획득할 수 있습니다.
contract SimpleAccount {
function initialize(address anOwner) public virtual initializer {
_initialize(anOwner);
}
}
Safe 등 다른 주류 계약 지갑에서도 유사한 문제가 기본적으로 존재합니다. 과거 계약 지갑의 구현에서는 종종 계약 배포와 초기화를 하나의 거래로 패키징하여 원자적 작업을 구현하여 경쟁 문제를 피했습니다.
그러나 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 자체 또는 유효한 서명을 가진 경우에만 초기화 방법을 호출할 수 있도록 보장합니다. 가스 대납 상황을 고려할 때 후자가 더 일반적일 수 있습니다.
2. Delegation 계약의 저장 구조 충돌 문제
EIP-7702 상황에서 EOA는 Delegation 업데이트를 자주 수행할 수 있으며, 이는 Proxy 업그레이드와 같습니다. 각 Delegation 계약은 서로 다른 지갑 제공자나 DApp 개발자가 제공할 수 있으며, 서로의 구현이 다를 수 있습니다. 단일 개발자 상황에서의 계약 업그레이드와는 달리 각 버전의 호환성을 보장하기가 쉽지 않습니다.
서로 다른 Delegation 계약의 변수 저장 구조는 완전히 다를 가능성이 높으며, 계약 간에 동일한 Storage slot을 재사용하면 잘못된 데이터를 읽거나 예상치 못한 데이터를 쓸 수 있어 계약 기능에 이상이 생길 수 있습니다. 데이터가 한 번 잘못되면 수정을 위해 높은 기술 능력이 필요하며, 일반 사용자는 이를 처리하기 어렵습니다.
여기서 개발자에게 ERC-7201의 Storage 관리 모드를 사용하여 Namespace 방식을 채택하여 독립적인 Storage 공간을 사용하고, 기본 0x0으로 시작하는 slot을 사용하지 않도록 권장합니다.
3. Delegation 권한 관리 문제
EIP-7702는 Proxy 계약과 매우 유사하지만, EIP-7702 상황에서는 이더리움 프로토콜 수준에서 implementation 계약을 관리합니다. 이는 Proxy가 고정 불변의 소유자를 가진 것과 같습니다. 따라서 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로 ETH를 전송하면 EOA 대리 계약의 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