그동안 Ethereum에서 사용자는 EOA(External Ownerd Account)를 통하여 Transaction를 찍거나, CA(Contract Account)와 상호 작용을 하였습니다.
위에서 설명한 것처럼 EOA는 개인 키를 보유한 사용자가 모든 행위를 수행할 수 있었지만, On-Chain의 Code를 실행하기 위해서는 Contract를 Deploy하고 CA와 상호 작용해야 했습니다.
CA는 자신의 Code를 실행하기 위해서는 사용자의 상호작용이 필요하다는 단점과 코드 변경이 쉽지 않다는 단점이 있었습니다.
- Upgradable Proxy를 통해 코드를 변경할 수는 있지만, 이러한 방법도 Code Deploy 후 Proxy 변경이 필요함
즉, On-Chain의 Code를 실행하기 위해서는 Contract를 배포한 뒤, EOA로 Transaction을 찍어야 한다는 사실이 많은 사용자들에게 불편을 야기했습니다.
Account Abstraction은 바로 이러한 문제들을 해결하기 위해 나온 개념입니다. 계정을 추상화하여 Contract의 형태로 구현함으로써 위와 같은 불편사항을 없애고 다양한 On-Chain 내 Code 실행과 Transaction의 발행을 목표로 하고 있는 것이죠!
참고로 현재 EIP에는 Account Abstraction과 관련된 많은 EIP가 존재하고 있습니다.
- EIP-2771: account abstraction using meta-transactions
- EIP-2938: changing the Ethereum protocol to support account abstraction
- EIP-3074: upgrading externally-owned accounts for account abstraction
- EIP-4337: account abstraction without changing the Ethereum protocol
이 중에서 Ethereum Protocol의 변경 없이 AA를 구현할 수 있는 EIP-4337이 현재 가장 유망하다고 볼 수 있습니다.
EIP-4337은 사용자가 수행하기를 원하는 작업을 UserOperation이라고 하는 ABI Encoding 구조로 패키지화 합니다.
사용자는 UserOperation 객체를 user operation Mempool로 전송하며, Bundler는 user operation Mempool에서 수집한 UserOperation들을 모아 Bundler Transaction을 생성합니다.
이후, 생성된 Bundle Transaction을 검증하기 위해 Entrty Point Contract를 호출합니다.
※ Bundler : user operation Mempool에서 UserOperation 객체를 모아 검증 및 실행하고, Bundle Transaction을 생성하는 노드
Entry Point Contract
Entry Point Contract의 handleOps 함수는 검증 Loop와 실행 Loop를 포함해야 합니다.
검증 Loop에서는 각각의 UserOperation에 대해 아래와 같이 작업을 수행합니다.
- 지갑이 아직 존재하지 않는 경우, UserOperation 내에 명시된 initCode를 사용하여 지갑을 생성함
(만약, 지갑이 존재하지 않으면서, initCode가 비어있다면, 반드시 호출에 실패해야 함) - 지갑이 존재하는 경우, validateUserOp 함수를 호출하며, 이때 UserOperation과 Fee를 함께 전송함
- 이때 지갑에서는 Operation의 Signature를 검증해야하며, 검증이 유효하다고 판단한 경우에만 Fee를 지불해야함
- ValidateUserOp 함수가 실패한 경우, handleOp는 해당 Opeartion을 건너 뛰거나 Revert할 수 있음
실행 Loop에서는 각각의 UserOperation에 대해 아래와 같이 작업을 수행합니다.
- UserOperation의 Calldata 실행함. 이때 CallData를 Parsing 하는 방법은 Wallet에 달려있음
- 실행 후 남은 Fee는 Wallet에 반환됨
참고로 UserOperation을 수락하기 이전에 Bundler는 RPC 메서드를 통해 simulateWalletValidation 함수를 호출하여 로컬에서 서명의 유효성을 검증하고 실제로 수수료를 지불하는 지 시뮬레이션해야 합니다.
Extenstion: paymasters
Dapp을 조금 사용해보셨다면, Tranaction 수수료가 부족하여 ETH를 채워놓으셨던 경험이 있으실 것 같습니다.
Paymasters는 Dapp 개발자가 사용자의 수수료를 보조하거나, ERC-20과 같은 토큰으로 수수료를 지불할 수 있도록 도와주는 역할을 합니다.
만약 Paymaster가 0이 아닌 경우( 존재하는 경우), 아래와 같은 다른 로직을 타게 됩니다.
만약 Paymaster가 존재한다면, 검증 Loop 실행 과정에서 handleOps 함수는 validateUserOp 함수를 호출하는 것 외에도 Paymasters가 충분한 ETH를 보유하고 있는 지 검증합니다. 이후, paymaster의 validatePaymasterUserOp 함수를 호출하여 Operatorion에 대한 검증을 수행할 것인 지 확인합니다.
이때 Paymasters가 수수료를 지불하기 때문에, ValidateUserOp 함수는 requirePrefund가 0인 상태로 호출되어야 합니다.
이후, 실행 Loop 과정에서 handleOps 함수는 main execution call을 한 뒤, Paymaster의 postOP 함수를 호출합니다.
이때 Paymaster가 악의적인 목적을 가지고 있다면, DoS가 가능합니다. 이를 방지하기 위한 방안으로는 평판 시스템 등이 있습니다.
위와 같은 표준으로 구현된 Account Abstraction은 기존에는 수행할 수 없던 아래와 같은 기능들이 가능하게 되었습니다.
- 계정을 추상화함으로써, CA가 아니더라도 On-Chain Code를 실행할 수 있게 되었습니다. EOA와 CA가 합쳐졌다고도 볼 수 있을 것 같아요.
- Paymasters를 통하여, 수수료에 대한 선택 사항이 조금 더 넓어졌습니다. (개발자가 지불하거나 ERC-20과 같은 대체 수단을 사용하는 등)
EIP-4337의 경우, Ethereum Protocol의 변화 없이 Contract를 통하여 추상화 과정을 진행하고 있습니다. 이때 Contract의 구현 코드에 따라 해킹과 같은 이슈가 발생할 가능성은 있을 것 같습니다.
다만, Account Abstraction 지원은 사용성 개선 측면과 애플리케이션 확장성 향상 측면에서는 꼭 필요한 기능이라고 생각합니다. OpenZeppelin과 같이 그래도 안전한 표준 코드를 사용하여 보안성을 일정 수준으로 가져가는 등의 방식으로 두 마리 토끼를 모두 잡아야할 것 같다는 생각이 드네요.
Reference
https://github.com/ethereum/EIPs/blob/3fd65b1a782912bfc18cb975c62c55f733c7c96e/EIPS/eip-4337.md
'Hack > Cryptocurrency' 카테고리의 다른 글
Solana SPL Token CLI 설치 방법 (0) | 2024.02.02 |
---|---|
BRC-20이란? (0) | 2024.01.16 |
23년 10월 7일, Stars Arena Drained of $3M (0) | 2023.10.09 |
23년 9월 12일, CoinEX Hacking 사고 분석 (0) | 2023.09.30 |
BGP Hijacking을 통한 Balancer Web Site 이용자들의 자산 탈취 (0) | 2023.09.30 |
댓글