EIP-7702: 기존 EOA는 어떻게 코드를 실행할까
한 지갑에서 B에게 토큰 6개, C에게 4개를 보내려고 한다. 두 요청을 따로 보내면 첫 번째만 성공하고 두 번째는 실패할 수 있다. 두 전송을 한 번의 실행으로 묶되, 토큰은 지금 쓰는 주소에 그대로 두고 싶다.
새 스마트계정으로 자산을 옮기는 방법도 있다. 그렇다면 기존 주소가 프로그램을 실행하도록 만드는 방법은 없을까?
EIP-7702는 개인키로 제어하는 계정인 EOA에 실행할 코드를 지정하는 방식을 추가한다. 가스비 대납은 이 변화로 만들 수 있는 서비스 가운데 하나다. 먼저 계정에서 무엇이 바뀌고, 어떤 서명이 그 변경을 허용하는지 살펴보자.
주소를 옮기지 않고 두 전송을 묶고 싶다
EIP-7702를 지원하는 네트워크에서 주소 A가 토큰 T 100개를 가지고 있다고 하자. B와 C의 잔액은 모두 0이다. 목표는 A90/B6/C4이며, 세 주소의 토큰 합계는 계속 100개다. 소수 자릿수는 0이고 발행·소각·토큰 전송 수수료와 다른 동시 거래는 없다고 가정한다.
이 글의 A는 기존 EOA다. 개인키는 A가 제어하고, 주소도 A를 유지한다. 1편에서 사용한 별도 스마트계정을 이 주소로 옮기는 사례가 아니라, 같은 요구를 다른 계정 구조에서 살펴보는 예제다.
일반적인 EOA에서 토큰 계약 T의 transfer를 두 번 직접 호출한다면 각각 거래를 만들 수 있다.
첫 번째 거래로 B에게 6개를 보내고 두 번째 거래를 처리하기 전에 멈추면 A94/B6/C0이 된다.
이 상태도 유효한 결과지만, 두 전송을 한 묶음으로 처리하려는 의도와는 다르다.
배치 실행 코드를 가진 컨트랙트를 호출하는 방법을 생각할 수 있다.
다만 별도 컨트랙트가 단순히 T의 transfer를 호출하면, T가 보는 호출자는 그 컨트랙트다.
A의 잔액을 사용하려면 자산을 옮기거나, 별도의 사용 승인과 transferFrom 같은 연결이 필요하다.
EIP-7702는 여기서 A의 주소를 실행 주체로 유지하면서 다른 곳에 배포된 코드를 사용할 수 있게 한다.
A에 남는 것은 실행 코드를 가리키는 지정 정보다
주소 D에 두 호출을 순서대로 실행하는 코드가 이미 배포돼 있다고 하자. A는 EIP-7702의 authorization, 즉 위임 승인 서명으로 D를 실행 코드의 대상으로 지정한다.
네트워크가 유효한 승인을 처리하면 A의 코드 영역에는 D를 가리키는 위임 지정 정보가 기록된다. 실제 바이트 형식은 짧다.
0xef0100 || D의 20바이트 주소
||는 두 바이트열을 이어 붙인다는 표기다.
이 정보가 있는 A를 호출하면 EVM은 D의 코드를 읽어 A의 실행 맥락에서 실행한다.
실행 중 자신의 주소는 A이고, 사용하는 계정 저장 공간도 A의 것이다.
명세의 위임 지정 규칙이 이 동작을 정의한다.
따라서 이 코드가 토큰 계약 T를 호출하면, T는 A가 호출한 것으로 본다. T가 기록해 둔 A의 토큰 잔액을 그대로 사용할 수 있다. 토큰을 D로 옮기거나 D의 저장 공간을 A에 복사하는 과정은 없다.
| 구분 | 이 예제에서의 역할 |
|---|---|
| 주소 A | 토큰을 보유하고 위임된 코드를 실행하는 계정 |
| 주소 D | A가 사용할 실행 코드가 배포된 곳 |
| 토큰 계약 T | A·B·C의 잔액을 기록하고 전송을 처리하는 곳 |
D에 있는 코드를 재사용하더라도 여러 계정의 상태가 하나로 합쳐지는 것은 아니다. 각 계정은 자신의 주소와 저장 공간에서 실행한다.
위임 서명은 무엇을 승인하는가
위임 승인은 어떤 코드를 내 계정에서 사용할 것인가에 관한 서명이다. EIP-7702에서는 체인 ID, 위임할 코드의 주소, 계정 nonce를 묶어 서명한다. nonce는 승인 처리 시점의 계정 nonce와 대조해 같은 승인의 재사용을 막는 값이다.
| 서명에 담는 값 | 이 예제의 의미 |
|---|---|
| 체인 ID | 위임을 허용할 네트워크 |
| D의 주소 | A에서 실행하도록 지정할 코드 |
| A의 계정 nonce | 승인을 적용할 계정 상태의 순서 |
여기에는 “B에게 6개, C에게 4개”라는 전송 내용이 들어 있지 않다. 누가 어떤 호출을 실행할 수 있는지는 D의 코드에서 별도로 확인해야 한다. 코드를 선택하는 승인과 그 코드로 특정 작업을 실행하는 승인은 역할이 다르다.
이 예제의 D는 A 자신이 보낸 배치 요청만 실행하도록 설계했다고 가정하자. A는 자기 계정으로 보내는 거래에 두 전송 내용을 담아 서명한다. 이 거래의 서명이 구체적인 실행 내용을 승인하고, D는 호출자가 A인지 확인한다. 제3자가 제출하도록 확장한다면 D가 검증할 별도의 실행 서명이나 권한 정책이 필요하다.
위임 승인들은 새 거래 형식인 0x04 거래의 authorization_list에 들어간다.
바깥 거래에도 별도의 발신자 서명이 있으며, 위임을 승인한 계정과 바깥 거래를 보내는 계정은 다를 수 있다.
위임 설정과 실행을 한 거래에 함께 담을 수도 있다. 설명을 위해 두 역할을 나눴을 뿐,
반드시 온체인 거래를 두 번 보내야 한다는 뜻은 아니다.
체인 ID에는 체인을 한정하지 않는 특수값 0도 있다. 이 예제에서는 사용할 네트워크의 ID를 명시한다.
서명 형식과 검증 순서는 set-code 거래 규칙을 따른다.
두 호출이 A의 주소에서 실행된다
위임을 설정한 A가 자신의 주소로 배치 실행 요청을 보내면 다음 흐름이 된다. 여기서는 D가 실패한 하위 호출을 전체 실행의 실패로 처리하도록 설계했다고 가정한다.
A가 배치 실행 요청에 서명
↓
A의 주소로 거래 전달
↓
D의 코드를 A의 맥락에서 실행
↓
A → T: B에게 6개 전송
↓
A → T: C에게 4개 전송
↓
토큰 잔액 A 90 / B 6 / C 4
첫 호출 뒤의 중간 잔액은 A94/B6/C0이지만, 두 번째까지 성공한 실행 결과는 A90/B6/C4다. 반대로 T가 C로의 두 번째 전송을 거절하고 D가 전체를 되돌리면, 첫 번째 전송도 함께 되돌아가 잔액은 A100/B0/C0으로 남는다.
이 원자성은 예제에서 선택한 배치 실행 코드의 동작이다. 실패를 무시하고 다음 호출을 계속하는 코드도 만들 수 있으므로, EIP-7702만 적용하면 모든 배치가 자동으로 전부 성공하거나 전부 취소된다고 볼 수는 없다.
또한 ERC-20 전송은 컨트랙트에 따라 false를 반환할 수 있다.
예제의 D는 이런 결과도 실패로 다루어야 한다. 단순히 저수준 호출이 되돌려지지 않았는지만 확인해서는 부족하다.
가스비는 이 편에서 A가 직접 낸다고 두자. A가 0.01 ETH를 가지고 있고 이 거래에 실제로 부과된 비용을 설명용으로 0.001 ETH라 놓으면, 남는 ETH는 0.009다. 토큰 합계 100개와 가스비 지출은 별도로 계산한다. 실패한 거래도 실행에 비용을 쓸 수 있다. 이 수치는 실제 측정값이나 고정 요금이 아니다.
거래가 끝나도 위임은 남는다
EIP-7702의 위임은 한 번 실행하고 사라지는 임시 설정이 아니다. A가 D를 가리키도록 설정했다면 이후 A를 호출할 때도 그 코드를 사용한다. 다음 배치 실행마다 같은 위임 승인을 새로 등록할 필요는 없다.
다른 코드를 쓰려면 새 authorization으로 위임 대상을 바꾼다. 위임을 해제하려면 위임 주소를 영 주소로 지정한 유효한 승인을 처리한다. 그러면 A의 코드 지정 정보가 지워진다. 이때 계정 저장 공간이나 토큰 계약에 남긴 사용 승인까지 함께 초기화되는 것은 아니다.
여기서 실패의 범위를 한 번 더 구분해야 한다.
한 0x04 거래에서 위임 설정과 배치 실행을 함께 처리했더라도,
뒤의 배치 실행이 실패했다고 앞에서 처리한 위임 지정까지 되돌아가지는 않는다.
토큰 잔액은 A100/B0/C0으로 되돌아가면서 A에는 D를 가리키는 위임이 남을 수 있다.
위임 처리 규칙은 이 두 단계의 차이를 명시한다.
따라서 “거래 실패”를 보고 모든 설정이 이전 상태로 돌아갔다고 판단해서는 안 된다. 실행 결과와 계정의 위임 상태를 각각 확인해야 한다.
기능을 더하는 만큼 실행 권한도 설계해야 한다
코드를 지정했다고 해서 지갑의 기능이 완성되는 것은 아니다. 배치 실행, 복수 서명, 특정 앱만 사용할 수 있는 권한과 사용 한도는 위임 코드가 구현할 수 있는 기능이다. EIP-7702가 그 정책을 일괄 제공하지는 않는다.
특히 D의 코드는 A의 자산과 저장 공간에 영향을 줄 수 있다. 신뢰할 코드를 선택하고, 누가 실행 요청을 보낼 수 있는지 확인하는 일이 계정의 권한 설계가 된다. 기존 EOA의 개인키도 계속 중요하다. 위임했다고 개인키로 제어하던 계정의 성격이 모두 사라지는 것은 아니다.
초기화도 따로 생각해야 한다. D를 배포할 때 실행한 생성자가 A에서도 다시 실행되지는 않는다. A에 소유자나 권한 설정을 기록해야 한다면, 누가 그 초기화를 허용하는지 검증해야 한다. 위임 대상을 바꿀 때는 A에 남아 있는 저장 공간을 새 코드가 어떻게 해석하는지도 맞춰야 한다. 명세의 초기화·저장 공간 설명은 이 문제를 다룬다.
이 원리는 ERC-4337과도 연결할 수 있다. 위임 코드가 ERC-4337 스마트계정에 필요한 인터페이스와 검증을 제공한다면, 기존 EOA 주소를 사용하는 계정도 그 실행 흐름에 참여할 수 있다. 위임만 설정하면 Bundler와 Paymaster가 자동으로 생기는 것은 아니다. EIP-7702의 계정 추상화 호환 설계는 이렇게 계정의 기능과 실행 인프라를 연결하는 방향을 설명한다.
이번 예제에서는 같은 주소 A가 두 전송을 실행하도록 확장했다. 다음 질문은 이 실행 요청을 누가 제출하고 비용을 부담할 것인가다. 다음 편에서는 BXB가 고객 계정의 거래 권한과 sponsor의 비용 부담을 어떻게 연결하는지 살펴본다.