soobook
ETHEREUM

Ethereum Account Abstraction 101 (2026)

컨트랙트가 계정 역할을 하면 서명 방식, gas 결제, 트랜잭션 묶음을 자유롭게 정의할 수 있다. 이 발상이 EIP-1271부터 EIP-8141까지 4단계 진화로 자리 잡았다.

이더리움 계정 추상화(Account Abstraction, 이하 AA)는 한 번의 protocol 변경으로 도입된 게 아니라, 사이드 인프라에서 시작해 점차 protocol native로 옮겨가는 4단계로 쌓여 왔다.

왜 AA가 필요했나

EOA(Externally Owned Account)는 secp256k1 keypair 하나로 정의된다. 주소가 곧 public key의 keccak 해시이고, 트랜잭션 발신은 그 keypair가 만든 ECDSA 시그니처로만 가능하다.

이 단순함이 이더리움의 출발점이지만, wallet UX 입장에선 세 가지 한계가 도드라진다.

첫째, Signature Scheme 이 ECDSA secp256k1 하나로 잠겨 있다. 패스키, 멀티시그, MPC 분산 서명 같은 다른 인증 방식을 EOA 위에 그대로 얹을 길이 없다.

두 번째는 gas다. 트랜잭션 발신자 본인이 ETH로 직접 결제해야 한다. 신규 사용자가 트랜잭션 한 건이라도 보내려면 먼저 ETH를 어딘가에서 받아 와야 하고, 이게 onboarding 과정에서 가장 큰 마찰점으로 작동한다.

마지막으로 한 트랜잭션이 한 컨트랙트 호출로 한정된다. EOA의 트랜잭션 페이로드는 to + value + data 한 쌍뿐이라, approveswap을 하나의 원자적 단위로 묶을 길이 없다.

사용자는 두 번 서명하고 두 번 confirm하며, 두 트랜잭션 사이에 mempool 상태가 노출돼 frontrunning에 열린다.

Multicall이나 EIP-2612 permit 같은 우회로가 있지만 모두 별도 컨트랙트 트릭이거나 토큰별 추가 표준이고, EOA의 native 기능은 아니다.

이 셋을 동시에 푸는 결론으로 “계정이 컨트랙트가 된다”는 추상화에 이르렀다.

컨트랙트는 시그니처 검증 로직을 자체적으로 정의하고, gas는 다른 주체가 대납하고, 한 호출 안에서 여러 호출을 묶는다.

 

컨트랙트가 계정이 된다\textbf{\text{컨트랙트가 계정이 된다}}

 

EIP-1271: 컨트랙트의 서명 검증

컨트랙트는 private key가 없으니 ECDSA 시그니처를 만들 수 없다. 그러나 dapp 입장에선 “이 컨트랙트가 이 메시지에 동의했는가”를 묻고 싶다.

예를 들어 Safe 같은 멀티시그 wallet이 OpenSea의 listing에 서명한 셈으로 처리되려면, 컨트랙트가 “동의함”이라는 응답을 표준 인터페이스로 돌려줘야 한다. EIP-1271이 그 인터페이스를 정의한다.

interface IERC1271 {
    function isValidSignature(bytes32 hash, bytes memory signature)
        external
        view
        returns (bytes4 magicValue);
}

컨트랙트가 0x1626ba7e(= bytes4(keccak256("isValidSignature(bytes32,bytes)")))를 반환하면 유효, 그 외 값은 무효로 간주한다.

컨트랙트는 내부 정책을 자유롭게 정한다. 멀티시그라면 N-of-M 검사, 패스키라면 P-256 검증, MPC라면 분산 서명 조립 결과를 검증한다.

1271의 진짜 가치는 “서명”이라는 개념을 키 소유 증명에서 정책 통과 증명으로 바꾼 데 있다. 누가 키를 들고 있느냐가 아니라, 컨트랙트가 정한 규칙이 통과됐느냐가 동의의 기준이 된다. 이후의 모든 AA 표준은 이 추상화 위에 올라간다.

ERC-4337: alt mempool 위의 AA

컨트랙트가 트랜잭션 발신 주체처럼 동작하도록 만든 추상화를 Smart Account라 부른다. 일반 컨트랙트와 다르게 자기 자산을 누가 움직일 수 있는지 검증 로직을 코드가 직접 정의한다.

시그니처가 ECDSA여야 한다거나 single signer여야 한다는 protocol 차원의 강제가 없고, 컨트랙트가 정한 정책 통과 증명이 곧 동의의 기준이 된다.

ERC-4337은 이 Smart Account 추상화를 alt mempool 위에서 굴러가게 만드는 표준이다. alt mempool이란 노드의 표준 트랜잭션 풀이 아니라 Bundler들이 자체 운영하는 별도의 P2P 네트워크를 가리킨다.

UserOp은 ECDSA 트랜잭션이 아니라 데이터 객체라서 노드 mempool로는 들어가지 않고, 이 별도 풀에서 떠돌다가 Bundler 손에 잡혀 온체인 트랜잭션으로 묶인다.

핵심 제약은 protocol 자체를 손대지 않는 것이다. EOA만 트랜잭션을 발신할 수 있는 구조를 그대로 두고, 옆에 별도 mempool과 처리 파이프라인을 만들어 컨트랙트 계정이 트랜잭션을 보낸 것 같은 효과를 만들어 낸다.

sequenceDiagram
    box rgba(255, 230, 200, 0.25) Off-chain
    actor User
    participant App as Wallet App
    participant Mempool as Alt Mempool
    participant Bundler
    end
    box rgba(200, 230, 255, 0.25) On-chain
    participant EntryPoint
    participant Account as Smart Account
    participant Paymaster
    end

    User->>App: confirm intent
    App->>Mempool: submit signed UserOp
    Bundler->>Mempool: pull UserOps
    Bundler->>EntryPoint: handleOps(userOps)
    Note over Bundler,EntryPoint: Bundler가 자기 ETH로 gas 결제
    EntryPoint->>Account: validateUserOp(userOp, hash, missingFunds)
    EntryPoint->>Paymaster: validatePaymasterUserOp()
    EntryPoint->>Account: execute calldata

4개의 핵심 요소가 있다.

  • UserOperation: 사용자의 의도를 담은 객체. sender, callData, gas limit들, signature, paymasterAndData 등을 포함한다. UserOp은 트랜잭션이 아니라 데이터 구조이다. Bundler들이 자기들끼리 운영하는 별도 P2P 네트워크(alt mempool) 또는 Bundler가 노출한 RPC endpoint를 통해 떠돈다. 노드 mempool에 진입하는 시점은 Bundler가 UserOp을 모아 handleOps() 트랜잭션으로 묶어 발신할 때다.
  • EntryPoint: 검증과 실행을 표준화한 싱글톤 컨트랙트. 메인넷과 대부분 L2에 동일 주소(v0.7 기준 0x0000000071727De22E5E9d8BAf0edAc6f37da032)로 deploy돼 있고, 모든 4337 어카운트가 이 컨트랙트를 통해서만 호출된다. 4337 생태계에서 신뢰의 중앙점 역할을 한다. Bundler가 가짜 검증을 통과시켜도 EntryPoint가 자기 안에서 다시 검증하기 때문에 위조가 불가능하다.
  • Bundler: alt mempool에서 UserOp을 모아 EntryPoint로 묶어 보내는 actor. Bundler 자신은 그냥 EOA로 동작한다.
  • Paymaster: 다른 주체가 gas를 대납하거나 ERC-20 토큰으로 결제하게 만드는 컨트랙트. Onboarding 마찰을 푸는 핵심 조각이다.

spec은 인터페이스만 정하고 내부 정책은 구현체가 자유롭게 정한다. EntryPoint는 단일 표준이지만, Bundler는 Pimlico, Alchemy, Stackup, Biconomy 같은 인프라 회사들이 각자 운영하고, Smart Account implementation도 Safe, Kernel(ZeroDev), Coinbase Smart Wallet, MetaMask Smart Account, Argent 등 여러 갈래로 갈린다.

Bundler 간 simulation 호환성은 ERC-7562가 별도로 보장한다. ERC-7562는 한 Bundler에서 통과한 UserOp이 다른 Bundler에서도 같은 결과로 통과하도록 validation 단계의 opcode와 storage 접근 규칙을 정의한다.

스마트 어카운트가 implement해야 하는 핵심 함수는 validateUserOp 하나다.

function validateUserOp(
    UserOperation calldata userOp,
    bytes32 userOpHash,
    uint256 missingAccountFunds
) external returns (uint256 validationData);

이 함수 안에서 어카운트는 시그니처를 검증한다. 표준 패턴은 EIP-1271의 isValidSignature을 그대로 호출하는 것. 즉 1271은 4337의 검증 단계 안에 끼워 넣어진 인터페이스다.

4337 어카운트의 99%가 이 패턴을 따르고, 그래서 OpenZeppelin이나 Safe의 어카운트 코드를 보면 두 표준이 자연스럽게 한 곳에 묶여 있다.

4337은 검증과 실행을 강하게 분리한다. validation 단계에서는 외부 컨트랙트의 storage를 읽거나 BLOCKHASH 같은 환경 의존 opcode를 못 쓰도록 제한한다.

Bundler가 simulation으로 미리 검증한 결과가 실제 실행에서도 그대로 재현돼야 mempool DoS를 방지하기 때문이다.

사용자 입장의 gas 흐름은 EOA를 쓸 때와 완전히 뒤집힌다. 온체인 트랜잭션을 발신하는 주체는 사용자가 아니라 Bundler이고, Bundler가 자기 EOA로 handleOps()를 만들면서 자기 ETH로 gas를 결제한다.

그 비용은 validateUserOp에 전달되는 missingAccountFunds만큼 Smart Account가 EntryPoint에 prefund하거나 Paymaster가 대납해 회수된다.

그래서 사용자는 자기 EOA에 ETH가 한 푼도 없어도 트랜잭션을 보낸다. Paymaster가 sponsor하면 그대로 0이고, 그렇지 않더라도 Smart Account 컨트랙트 잔액이나 EntryPoint deposit으로 충당하면 된다.

ETH 마찰은 사용자에게서 Paymaster나 dapp 운영자에게로 옮겨간다. 이게 4337이 onboarding에 주는 실제 효과다.

4337의 흠은 “alt mempool 의존”이다. Bundler 인프라가 깔리지 않은 체인에선 동작하지 않고, 일반 트랜잭션과 다른 경로라 wallet UX를 두 갈래로 갈라놓는다. 7702와 8141은 이 흠을 단계적으로 메운다.

EIP-7702: EOA의 코드 위임

Pectra 하드포크 이후 활성화됐다. 4337은 신규 스마트 어카운트는 잘 풀지만, 이미 자산이 쌓인 EOA를 어쩌지 못했다.

예를 들면, 사용자가 4337의 혜택(e.g. 가스비 대납)을 누리려면 EOA에서 새 스마트 어카운트로 자산을 옮기거나, ERC-2771 같은 meta-transaction relayer를 따로 써야 했다. 7702는 이 마찰을 EOA 자리에서 직접 해결한다.

새 트랜잭션 타입 SET_CODE_TX_TYPE(type 4)를 도입해, EOA가 트랜잭션 발신 시 authorization tuple을 함께 첨부할 수 있게 했다.

authorization_list: [
    { chain_id, address, nonce, signature },
    ...
]

각 tuple은 “이 주소(컨트랙트)의 코드를 내(EOA) 코드로 위임한다”는 EOA의 서명이다. set_code 트랜잭션이 블록에 포함되는 순간 EOA의 코드 슬롯에 delegation indicator(0xef0100 || address)가 박히고, 같은 블록 안의 다음 호출부터 위임된 코드로 실행된다.

위임은 새 7702 트랜잭션이 다른 위임을 박을 때까지 유지된다 (0x0 주소로 위임하면 해제). 다만 이 변경도 일반 state change라 reorg되면 함께 되돌아간다. 7702 spec이 별도 finality 메커니즘을 정의하지 않기 때문이다.

그래서 위임과 실제 실행 호출을 같은 트랜잭션 안에 묶어 atomic하게 처리하는 방식이 보통이다.

flowchart LR
    A[EOA holder] -- signs auth tuple --> B[type-4 tx with authorization_list]
    B -- delegates code slot --> C[Smart Wallet contract]
    C -- batch / paymaster / session key --> D[Execution]

가스 대납이 어떻게 가능한지가 자주 막히는 지점이다. type-4 트랜잭션의 발신자(=가스를 결제하는 EOA)는 위임 대상 EOA와 같을 필요가 없다는 게 출발점이다.

먼저 EOA가 자기 type-4 트랜잭션을 직접 발신하면서 자기 코드 슬롯을 wallet 컨트랙트로 위임하는 경우. 이때는 EOA가 가스를 낸다.

가스 대납 패턴은 이렇다. EOA는 authorization tuple만 오프체인에서 서명해 sponsor(relayer 또는 Bundler)에게 넘긴다. sponsor가 자기 EOA로 type-4 트랜잭션을 발신하면서 그 tuple을 authorization_list에 첨부한다.

type-4 트랜잭션의 발신자가 sponsor이므로 가스도 sponsor가 결제하고, 위임 대상 EOA는 한 푼도 쓰지 않는다. 같은 트랜잭션 안에서 sponsor는 위임이 적용된 EOA(이제 wallet 컨트랙트처럼 동작)의 batch 함수를 호출해 approve + swap + supply 같은 묶음을 atomic하게 처리한다.

4337과 결합되면 sponsor 자리에 Bundler가 들어가고 paymaster가 가스 정산을 맡는다. 7702가 4337 인프라를 통째로 재활용하는 이유다.

7702는 EOA의 주소, 잔액, nonce, 트랜잭션 history를 그대로 둔 채 wallet 컨트랙트 동작만 얹는다. 사용자는 zksync로 자산을 bridge하거나 새 wallet으로 복사할 필요 없이, 같은 주소에서 batch call, paymaster gas 대납, session key 같은 4337 기능을 누린다.

7702와 4337은 경쟁이 아니라 보완이다. 신규 사용자는 4337 스마트 어카운트로 시작하고, 기존 EOA 사용자는 7702로 같은 인프라(Bundler, Paymaster, EIP-1271)에 진입한다. wallet 입장에선 두 경로가 같은 어카운트 코드를 재사용한다.

7702는 동시에 새 보안 모델을 만든다. EOA가 위임한 컨트랙트가 악의적이면 EOA의 잔액 전부가 단번에 빠져나간다.

그래서 wallet UI는 위임 대상 컨트랙트를 명확히 보여주고, 잘 검증된 어카운트 implementation(예: Safe 7702 모듈, MetaMask Smart Account)으로 위임을 한정해 주는 게 표준 관행이 됐다.

EIP-8141: protocol native AA

8141의 한 줄 정의는 “트랜잭션을 frame 단위로 분해한다”이다. 4337이 EntryPoint 컨트랙트로 풀던 검증 분리 구조를 protocol 본체로 끌어올린 셈이다.

새 트랜잭션 타입 FRAME_TX_TYPE이 도입되고, 그 안에 frame 시퀀스가 담긴다.

frame은 세 종류다.

  • validation frame: 시그니처가 유효한지 검사한다. 어카운트 컨트랙트가 검증 로직을 정의한다.
  • payment frame: gas를 누가 어떻게 결제하는지 정의한다. paymaster를 protocol native로 표현한 것이다.
  • execution frame: 실제 호출 묶음을 실행한다. batch call이 1급 시민이 된다.

이 분해가 protocol native가 되면 두 가지 효과가 따라온다.

우선 Bundler가 더 이상 필수가 아니다. 네이티브 mempool이 frame transaction을 그대로 받는다. 4337이 alt mempool 의존으로 갈라놓았던 wallet UX 두 갈래가 다시 하나로 합쳐진다.

한편 validation frame이 ECDSA를 강제하지 않는다. 어카운트 컨트랙트는 임의의 시그니처 스킴을 정의할 수 있고, post-quantum 알고리즘으로 가는 off-ramp가 protocol 차원에서 열린다.

양자 컴퓨팅이 secp256k1을 깨는 시점에도 트랜잭션 모델 자체를 갈아엎지 않고 검증 frame만 갈아 끼우면 된다.

4337에서 8141로의 이행은 코드 reset이 아니다. 8141 활성화 후에도 4337 EntryPoint와 어카운트는 그대로 동작한다. 단지 EntryPoint를 “컨트랙트 hop”으로 거치지 않고, frame validation 안에서 같은 검증 로직(즉 EIP-1271 호출)을 직접 호출하는 경로가 새로 열릴 뿐이다. 4337 어카운트 코드는 그대로 쓸 수 있다.

정리

EIP-1271은 “컨트랙트의 동의 표명”을 표준화했다. 키 소유 증명이 아니라 정책 통과 증명이라는 추상화가 이 단계에서 만들어졌다.

그러나 컨트랙트는 여전히 트랜잭션 발신자가 될 수 없었다.

ERC-4337은 alt mempool과 EntryPoint로 그 한계를 우회했다. 컨트랙트 어카운트가 트랜잭션을 보낸 것 같은 효과는 만들었지만, protocol 본체를 손대지 못해 Bundler 의존이 남았다.

EIP-7702는 기존 EOA를 4337 인프라로 끌어올렸다. 신규/기존 사용자 모두가 같은 어카운트 코드와 같은 paymaster 인프라를 쓰게 됐다. 다만 트랜잭션 모델 자체는 EOA-centric으로 그대로 남았다.

EIP-8141은 트랜잭션 모델을 frame으로 분해해 검증을 protocol native로 만든다. 1271이 추상화한 정책 통과 증명이 mempool 위에서 1급으로 처리되고, 시그니처 알고리즘은 ECDSA에 묶이지 않는다.

네 단계는 결국 한 방향이다. 검증을 protocol 본체로 끌어올리는 흐름.

References