Account Abstraction & ERC 4337

jeff lee
Decipher Media |디사이퍼 미디어
18 min readAug 13, 2022

--

본 아티클에서는 Ethereum Account Abstraction을 다룹니다. 글에 들어가기 앞서서, 필자는 이더리움과 아무런 연관이 없음을 밝히며, 본문은 정보 제공을 목적으로 작성된 글이며, 투자 의사 결정에 대한 근거로 사용될 수 없습니다.

출처 : https://etherworld.co/2021/10/06/an-overview-of-account-abstraction-in-ethereum-blockchain/

Author
Jeff Lee(jeff lee)
Seoul Nat’l Univ. Blockchain Academy Decipher(@decipher-media)
Reviewed By 정재환

목차

  1. Introduction
  2. Ethereum Account
  3. Account Signer
  4. Account Abstraction
  5. Account Abstraction의 기술적 장벽
  6. Account Abstraction의 Use Case
  7. History of Account Abstraction

Introduction

이번 글에서 소개드릴 내용은 Ethereum의 Account abstraction에 대한 개념과 이를 구현하는 여러 방법 중 하나인 ERC4337입니다.

글은 전반부와 후반부로 나뉘어집니다.

전반부는 Account abstraction를 이해하기 위한 배경 지식인 Ethereum Account와 Abstraction에 대해 알아보고, Account abstraction가 어떤 문제를 해결하기 위해 탄생했는지, 어떤 역사가 있는지, 어떤 장점이 있는지에 대해 소개합니다.

후반부는 Account abstraction를 구현하기 위해 제안된 ERC4337의 컨셉을 소개하고, ERC4337의 구현체를 코드를 통해 분석합니다.

전반부는 비개발자분들도 쉽게 이해하실 수 있도록 내용을 구성했으나, 후반부에 코드를 소개하는 부분은 독자가 개발자임을 상정하고 쓰였음을 미리 안내드립니다.

Ethereum Account

Ethereum에는 ‘account’라는 개념이 존재합니다. 각각의 account는 ether balance를 가지고 있으며 일반적으로 지갑주소라고 알려져있는 ‘address’ 라는 42자리 문자열로 구분됩니다.

겉으로 보기에 동일한 42자리 문자열이지만, account는 두 가지 타입이 존재합니다.

출처 : https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf 19p
  • EOA(Externally owned accounts) : 메타마스크와 같은 지갑 어플리케이션으로 생성할 수 있습니다. EOA는 private key에 의해 control 되는 account입니다.
  • CA(Contract accounts) : 스마트 컨트랙트를 배포했을 때 생성되는 account입니다. CA는 네트워크에 배포된 코드에 의해 control 되는 account 입니다.

이더리움의 모든 account는 account를 식별하기 위한 고유한 데이터인 address와 4가지 필드를 가지고 있습니다. 이는 EOA와 CA 둘 모두에게 적용되는 필드입니다.

출처 : https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf 20p
  • address : account마다 고유하게 가지고 있는 20bytes의 숫자이자 42자리 문자열입니다(0xabcd…) 우리가 흔히 ‘주소’라고 이야기 할 때의 값을 의미합니다.
  • nonce : account가 전송한 트랜잭션의 개수를 나타내는 정수입니다. account가 트랜잭션을 전송할 때, 현재 계정의 nonce를 같이 첨부하여, 트랜잭션이 중복되어 전송되지 않았음을 보장하기 위해 사용됩니다. 컨트랙트의 경우, 트랜잭션을 전송할 수 없기 때문에 CA의 nonce는 해당 컨트랙트가 CREATE OPCODE를 통해 생성한 컨트랙트의 개수를 의미합니다.
  • balance: 해당 account가 보유하고 있는 ether balance를 나타내는 필드입니다.
  • codeHash : CA라면, codeHash 필드에 스마트 컨트랙트의 코드가 담기게 됩니다. 그러나 EOA는 해당 값에 빈 문자열(””)의 해시값이 담겨 있습니다.
  • storageRoot : 각 account는 storage trie를 가지고 있습니다. 이 storage trie는 컨트랙트의 데이터를 담고 있는 trie입니다. 이 trie의 root node를 해시한 값이 storageRoot입니다. default 값이 비어 있기 때문에, codeHash와 마찬가지로 EOA는 비어 있습니다.

EOA로는 트랜잭션을 실행할 수 있습니다. EOA는 해당 EOA의 private key에 의해 관리되며, 수수료로 가스를 지불해서 EOA로 트랜잭션을 실행할 수 있습니다.

반면 CA는 스스로 트랜잭션을 실행할 수 없으며, 오직 EOA로부터 트랜잭션을 실행하라는 응답에 대해서만 트랜잭션을 실행시킬 수 있습니다. 따라서 한 컨트랙트가 다른 컨트랙트로 트랜잭션을 실행해야 하는 상황에서도 무조건 시작은 EOA가 전송한 트랜잭션으로 시작되어야 합니다.

Account and Signer

이더리움 account의 출발은 signer 에서 시작합니다. signer는 다른 말로 키 쌍(key pair)이라고도 불리는데, 그 이유는 공개키(public key)와 비밀키(private key)로 이루어진 한 쌍 이기 때문입니다.

비밀키는 유저가 잘 간직하고 있어야 하는, 말 그대로 ‘비밀’키입니다. 비밀키는 비밀번호의 역할을 합니다. 정확히 말하면, 비밀키는 ‘서명(sign)’에 사용됩니다. 비밀키를 가지고 있는 사람만 생성할 수 있는 서명을 통해 해당 비밀키를 가지고 있음을 인증할 수 있습니다.

반대로 공개키는 은행 계좌와도 같아 누구에게나 공개해도 되는 키입니다. 비밀키에 의해 생성된 서명을 공개키로 해독함으로써, 이 서명을 보낸 사람이 해당 비밀키를 보유하고 있음을 알 수 있습니다.

출처 : 이해를 돕기 위해 제작된 이미지입니다

이더리움의 address는 signer의 public key로부터 얻어집니다. public key를 keccak256 해시를 통해 해시화 한 맨 뒤 20bytes를 account address로 사용합니다. 이 20bytes의 데이터(앞에 0x가 붙어서 42자리의 문자열)이 우리가 흔히 ‘이더리움 주소(account address)’라고 말하는 주소를 의미합니다.

출처 : 이해를 돕기 위해 제작된 이미지입니다

트랜잭션을 실행할 때 account를 소유하고 있는 유저가, 트랜잭션을 본인이 보냈음을 증명하기 위해서는 private key로 생성된 서명이 필요합니다. 유저는 트랜잭션을 실행하기 전에, 트랜잭션 데이터에 유저의 private key로 생성한 서명을 첨부해야 합니다. 이를 통해 이더리움 프로토콜에게 해당 트랜잭션이 본인이 실행했다는 것을 증명할 수 있게 됩니다.

출처 : https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf 28p & 자체 제작 이미지

트랜잭션 데이터와 동봉된 서명을 전달받은 이더리움 프로토콜은 다음과 같은 두 단계 작업을 수행합니다

  1. verification : 서명을 통해 해당 트랜잭션이 유저로부터 생성된 트랜잭션이 맞는지 검증(verify)합니다.
  2. execution : 트랜잭션을 실행하고 유저의 balance에서 트랜잭션에 수행된 수수료(가스)를 차감합니다.

What is Signature?

키 쌍으로 암호학적 서명을 만드는 방법은 여러 가지가 존재하지만, 이더리움에서는 ECDSA(Elliptic Curve Digital Signature Algorithm)라고 불리는 서명 알고리즘을 사용합니다.

서명은 트랜잭션의 전송 뿐만 아니라, 본인을 인증하기 위한 수단으로도 활용될 수 있습니다. 대표적으로 account의 식별에 활용할 수 있습니다. opensea의 경우, 사이트에 접속을 하면, 현재 접속한 account를 식별하기 위해 지갑에 서명을 요청하게 됩니다. 이를 통해 아이디와 비밀번호를 입력하는 로그인 절차 없이도 JWT 인증 토큰을 발급받고, 닉네임을 비롯한 프로필의 설정이나 소유하고 있는 collection 정보를 수정하는 등의 활동을 수행할 수 있습니다.

출처 : Opensea

Problem in Ethereum Account

Signer와 account가 사실상 동일한 이더리움의 아키텍처는 심플하다는 장점이 있습니다. 그러나 동시에 단점이 존재합니다.

가장 직관적으로 와닿는 단점은 비밀키의 분실입니다. 현재 이더리움의 account 시스템에서는 signer와 account가 분리될 수 없는 관계이기 때문에, 비밀키를 분실하면 account도 사용할 수 없게 됩니다. 크립토에 친숙한 사람들에게는 당연할 수 있겠지만, 비밀번호를 한 번 분실했을 때, 모든 데이터가 유실된다는 유저 경험이 기존 유저들에게 익숙한 경험인지에 대해서는 재고해봐야합니다.

두번째는 지갑 디자인의 다양성 저하입니다. 현재 키 쌍으로 account 인증에 필요한 서명을 생성하는 로직은 이더리움 프로토콜에 ECDSA 방식으로 하드코딩 되어 있습니다. ECDSA는 양자 컴퓨터에 취약하기 때문에, 이러한 방식을 고수하는 것은 미래에 위협으로 다가올 수 있습니다.

Account Abstraction

이러한 문제를 해결하기 위해 등장한 개념이 account abstraction입니다.

컴퓨터 공학에서 abstraction(추상화)이란 복잡한 내부적인 작동 과정을 숨기고, 핵심적인 기능만 간추리는 과정을 의미합니다. 예를 들어, 우리가 메타마스크로 트랜잭션을 실행한다고 할 때, 내부적으로는 트랜잭션 데이터를 생성하고, 생성된 트랜잭션 데이터에 private key로 서명하고 이를 블록체인에 전파하는 복잡한 과정을 거칩니다. 그러나 메타마스크는 ‘전송’ 이라는 하나의 기능으로 위 복잡한 과정을 숨기고 핵심적인 기능만을 제공합니다. 이러한 과정을 추상화라 일컫습니다.

이러한 추상화 과정을 account에 적용하고자 하는 시도가 account abstraction입니다.

Account Abstraction의 목적은 현재 EOA(Externally Owned Account)와 CA(Contract Account)의 두 타입으로 나눠진 account를 Contract Account하나로 만드는 것입니다. 즉 기존에 서로 다른 타입으로 존재하던 두 account를 ‘account’ 하나로 추상화함으로써 개발자나 사용자들이 이를 구별할 필요가 없도록 만드는 것입니다.

출처 : https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf 와 이해를 돕기 위해 제작된 이미지입니다.

Account Abstraction의 기술적 장벽

서로 다른 두 타입의 account를 contract account 하나로 통일하고자 하는 목표를 이루기 위해 해결해야 하는 기술적인 장벽이 존재합니다. 이는 모든 트랜잭션이 EOA로부터 시작되는 반면, EOA에서 시작되는 트랜잭션의 검증이 이더리움 가상머신이 아닌, 가상머신 이전에 이더리움 프로토콜에서 이루어진다는 점입니다.

이를 해결하기 위해서는 CA로 트랜잭션의 verification이 가능하도록 만들어야 합니다. 즉 트랜잭션의 검증과 실행까지 모든 과정을 이더리움 가상머신에서 수행되도록 만들어야 합니다.

출처 : https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf 와 이해를 돕기 위해 제작된 이미지입니다.

앞서 보았듯, 트랜잭션의 실행은 2가지 스텝으로 나누어집니다. 검증(verification)과 실행(execution)입니다.

  • verification: 사용자의 private key로부터 생성된 서명을 통해 해당 트랜잭션의 실행 주체가 account가 맞는지, 해당 트랜잭션이 유효한 트랜잭션인지 검증하는 절차입니다. 이 절차는 이더리움 가상머신에서 실행되지 않으며, 이더리움 프로토콜에서 수행됩니다.
  • execution : verification이 완료되면, 이더리움 가상머신을 통해 트랜잭션에 담긴 데이터가 실행되고, 해당 트랜잭션의 결과에 따라 이더리움 가상머신의 state가 변경됩니다.

즉 다시 말해, Account abstraction을 위해서는 현재 이더리움 프로토콜에 하드코딩 되어있는 트랜잭션의 검증 로직을 스마트 컨트랙트로 수행할 수 있도록 변경해야 합니다.

Use Case of Account Abstraction

Account Abstraction을 구현하기 위해 필요한 변화는 코어 레벨에서 시작되나, 이러한 코어 레벨에서의 변화를 통해 다양한 어플리케이션의 변화가 발생하고, 이에 수반한 여러 응용사례를 기대할 수 있습니다.

첫째, 검증 로직 자체를 커스텀 할 수 있습니다. 현재 트랜잭션의 검증은 키 쌍의 private key로 서명을 생성하고, 이 서명으로 올바른 account가 맞는지 확인하는 방식을 사용하고 있습니다. 그러나 verification logic 이 EVM에서 실행될 수 있다면, 각 account마다 검증 로직을 입맛에 맞게 변경할 수 있습니다.

예를 들어, account가 여러 signer를 통해 제어 될 수 있도록 검증 로직을 변경할 수도 있으며(Multi-sig), 혹은 account를 관리할 수 있는 signer를 주기적으로 변경하는 방식도 생각해볼 수 있습니다. 즉 비밀번호(private key)가 변경될 수 있는 이더리움 account의 구현도 가능합니다.(upgradeable wallet)

결국 account와 signer를 분리함으로써, 하나의 private key에 모든 account의 정보를 의존하지 않아도 된다는 장점이 있습니다.

둘째, 특정한 암호학적 서명 생성 방식에 의존하지 않아도 됩니다. 이더리움은 ECDSA를 채택했으나, 이는 양자 컴퓨터에 취약합니다. 만약 verification 로직을 따로 분리할 수 있다면, Schnorr signatures, BLS signatures 와 같은 다른 서명 로직을 사용할 수 있으며, 혹은 양자 내성이 있는 알고리즘인 Lamport/Winternitz와 같은 서명 로직을 사용할 수 있습니다.

셋째, 완전한 컨트랙트 지갑의 구현이 가능합니다. 현재 대표적인 컨트랙트 지갑인 gnosis wallet의 경우, 멀티시그 월렛으로 등장했으나, 사실 트랜잭션을 전송하기 위해서는 멀티시그를 관리하는 각 계정에 수수료로 사용되기 위한 이더리움을 보유해야 합니다.

그러나 account abstraction을 통해 모든 계정이 CA 하나로 통일된다면, 온전한 컨트랙트 지갑을 구현할 수 있습니다. 이 경우, 수수료로 사용되는 ether를 지갑 역할을 하는 컨트랙트에 보관하도록 함으로써 signer가 이더리움을 수수료로 지불하지 않아도 된다는 장점이 있습니다. 심지어 이더리움 대신 다른 토큰을 수수료로 지불하는 행위도 가능합니다.

History of Account Abstraction

출처 : https://etherworld.co/2021/10/06/an-overview-of-account-abstraction-in-ethereum-blockchain/

Account Abstraction의 개념은 2016년부터 제시되어져 왔습니다. EIP86이 그 시작입니다. 비탈릭 부테린은 서명의 검증 로직이 이더리움 프로토콜에 내장이 되어 있기에, 다른 추가적인 검증 로직을 적용할 수 없는 문제점을 제기하며 EIP86을 제안했습니다.

이를 시작으로 Account Abstraction가 필요하다는 인식이 이더리움 커뮤니티에 널리 퍼졌고, 이를 만들어내기 위해 다양한 제안이 올라왔습니다.

대표적인 제안은 2020년 9월에 올라온 EIP2938입니다. EIP2938은 EOA 대신 컨트랙트로부터 트랜잭션을 실행할 수 있게 프로토콜을 변경하는 제안입니다. 컨트랙트가 자체적으로 트랜잭션을 검증할 수 있고, 수수료를 지불하는 로직까지 수행할 수 있도록 일부 OPCODE를 추가하고, 기존 트랜잭션 타입에 더해 AATransaction(Account Abstraction Transaction)를 추가하자는 내용이 담겨 있습니다. 그러나 이 제안은 이더리움의 컨센서스 레벨에 상당히 중요한 부분을 바꿔야 하는 제안이며, 따라서 Ethereum 2.0을 개발하고 있는 상황에서 적용되기는 어려운 제안이었습니다.

이 때 최초로 컨센서스 레벨을 바꾸지 않고 등장한 제안이 있습니다. 바로 ERC4337입니다. 비탈릭 부테린, ETHless transaction을 연구하는 OpenGSN 소속의 개발자들과 이더리움 클라이언트를 구현하는 Nethermind 소속의 개발자들이 제안한 ERC4337은, 이더리움의 컨센서스 레이어를 건드리지 않고 AA를 구현할 수 있는 방안을 제안합니다. 컨센서스 레벨을 바꾸지 않기에, 이를 바로 적용할 수 있는 구현체까지 등장할 수 있었습니다. 아래는 ERC4337의 제안자들이 구현한 ERC4337의 구현체입니다.

https://github.com/eth-infinitism/account-abstraction

후반부에는 ERC4337의 컨셉과 함께 구현체를 분석해보겠습니다.

요약

  • Ethereum Account는 signer와 account가 단단히 결합되어 있어서 private key의 분실에 취약하며 서명 로직을 변경할 수 없다는 단점이 존재한다.
  • 이를 해결하기 위해 signer와 account를 분리하고, 완전한 컨트랙트 지갑을 구현할 수 있도록 하는 Account Abstraction가 등장했다.
  • Account Abstraction을 구현하기 위해서는 Verification logic를 EVM에서 처리할 수 있도록 이더리움 프로토콜을 변경해야 한다.
  • 그동안 컨센서스 레이어의 변경을 통해 Account Abstraction을 실현하자는 제안이 있었으나, ERC4337을 통해 컨센서스 레이어의 변경 없이 Account Abstraction을 실현할 수 있게 되었다.

References

--

--