ERC-6315 네임스페이스 계정 추상화 (ERC-2771 Namespaced Account Abstraction)
Review · 계정·지갑 · 2023-01-11 작성
가스비 대납 같은 메타트랜잭션을 처리할 때, 수신 컨트랙트가 포워더를 미리 신뢰하지 않아도 되도록 포워더마다 별도의 주소 공간(네임스페이스)을 부여하는 ERC-2771 확장입니다.
왜 필요한가
이더리움에서는 제3자가 사용자 대신 트랜잭션을 체인에 올려 주는 메타트랜잭션(meta-transaction) 방식이 쓰이고, 널리 쓰이는 ERC-2771은 이를 '신뢰된 포워더(trusted forwarder)'로 처리합니다. 이 구조에서는 수신 컨트랙트가 특정 포워더를 미리 신뢰해 두어야 하므로, 포워더는 수신 컨트랙트마다 신뢰를 얻어야 하고 사용자는 그 신뢰 관계 바깥의 포워더를 자유롭게 쓸 수 없습니다. 이 제안은 포워더마다 별도의 주소 공간을 두는 네임스페이스 방식을 도입해, 수신 컨트랙트의 사전 신뢰 없이도 메타트랜잭션을 처리하는 신뢰 불요(trustless) 계정 추상화를 목표로 합니다. 수신 컨트랙트는 호출이 들어온 시점에 호출자가 네임스페이스 포워더인지 직접 확인하고, 포워더를 거친 주소는 어느 포워더가 관리하는지까지 함께 구분해 다룹니다.
구현해야 하는 것
function isNamespacedTransaction() external view returns (bool);: 호출자가 네임스페이스 포워더인지 알려 줍니다. 수신 컨트랙트가 이 함수를 읽기 전용으로 호출해 true가 돌아오면 네임스페이스 트랜잭션으로 처리합니다.function transferNamespaced(address toForwarder, address toAddress, uint256 amount);: ERC-20 transfer의 네임스페이스 버전 예시입니다. 받는 쪽을 포워더 주소와 그 포워더가 관리하는 주소의 쌍으로 지정해 토큰을 보냅니다.function approveNamespaced(address spenderForwarder, address spenderAddress, uint256 amount);: ERC-20 approve의 네임스페이스 버전 예시입니다. 사용 권한을 줄 대상을 포워더 주소와 관리 주소의 쌍으로 지정합니다.function transferFromNamespaced(address fromForwarder, address fromAddress, address toForwarder, address toAddress, uint256 amount);: ERC-20 transferFrom의 네임스페이스 버전 예시입니다. 보내는 쪽과 받는 쪽 각각을 포워더 주소와 관리 주소의 쌍으로 지정합니다.
심층 설명
네임스페이스 포워더 인터페이스
포워더는 INamespacedForwarder 인터페이스를 구현합니다. 이 인터페이스에는 isNamespacedTransaction() 함수 하나만 있고 external view로 선언되어 bool 값을 돌려줍니다. 수신 컨트랙트는 이 함수의 반환값으로 호출자가 네임스페이스 포워더인지 판단합니다.
발신자와 포워더를 정하는 절차
수신(Recipient) 컨트랙트는 함수가 호출되면 호출자의 isNamespacedTransaction() 메서드를 STATICCALL로 실행해야 합니다(MUST). 이 호출이 revert하거나 false를 돌려주면 일반 트랜잭션으로 진행하며 호출자를 발신자로, 포워더를 영주소(zero address)로 식별해야 합니다. true가 돌아오면 네임스페이스 트랜잭션으로 인정하고 ERC-2771의 트랜잭션 서명자 주소 추출 절차로 발신자를 정하며 호출자를 포워더로 식별합니다. ERC-2771처럼 포워더 목록을 미리 등록하는 것이 아니라 호출 시점에 동적으로 판별합니다.
Namespaced 함수 확장 규칙
수신 컨트랙트에 address 타입 파라미터가 있는 함수가 있으면, 원래 이름 뒤에 Namespaced를 붙인 함수를 반드시 추가로 제공해야 합니다(MUST). 새 함수는 address 하나 대신 두 개를 받는데, 앞쪽은 포워더 주소, 뒤쪽은 그 포워더가 관리하는 주소입니다. ERC-20의 transferFrom처럼 address 파라미터가 여러 개인 함수는 원래 파라미터 하나당 두 개씩 받는 버전을 제공해야 합니다. 포워더 주소가 모두 영주소일 때 원래 함수는 새 함수와 동일하게 동작해야 합니다(MUST). 원문은 ERC-20 확장 예시로 transferNamespaced, approveNamespaced, transferFromNamespaced 세 함수를 제시합니다.
ERC-165 인터페이스 ID 등록
수신 컨트랙트는 ERC-165를 반드시 구현해야 합니다(MUST). ERC-165 인터페이스 ID를 등록할 때는 원래 인터페이스의 ID와 함께, 그 인터페이스의 Namespaced 함수 셀렉터들을 XOR해 만든 두 번째 인터페이스 ID도 등록해야 합니다. 이렇게 하면 외부에서 어떤 컨트랙트가 네임스페이스 확장을 지원하는지 조회할 수 있습니다.
하위 호환성과 다른 표준에서의 사용
이미 배포된 컨트랙트는 코드를 바꿀 수 없으므로 이 네임스페이스 제안의 혜택을 받을 수 없습니다. 이 한계는 ERC-2771에도 똑같이 적용됩니다. 다른 표준에서 이 제안을 사용할 때는 원래 인터페이스 ID와 Namespaced 인터페이스 ID를 둘 다 제공하는 것이 권장되며(SHOULD), 표준의 인터페이스 선언 자체에 Namespaced 버전 함수를 포함해서는 안 됩니다(MUST NOT).
설계 이유
자주 쓰이는 EIP마다 새 인터페이스를 따로 만드는 대신, 기존 함수에 address 파라미터를 덧붙이는 방식을 택했습니다. 원문은 이 방식이 네임스페이스 제안을 더 폭넓은 경우에 적용할 수 있게 하기 위한 선택이라고 설명합니다.
제안 상태
이 제안은 현재 Review 상태입니다. 아직 검토 중인 제안이므로 내용이 바뀌거나 진행이 멈출 수 있습니다.
쓸 때 주의할 점
- 신뢰 구조가 바뀝니다: 이 제안은 신뢰 관계를 재편합니다. 포워더는 이제 수신 컨트랙트의 신뢰를 받을 필요가 없지만 대신 자신을 사용하는 사용자들의 신뢰를 받아야 합니다. 포워더를 고르는 책임이 사용자에게 옮겨지는 셈입니다.