EIP-8288 멤풀 서명·증명 집계 (In-mempool signature and proof aggregation)
콜 결정 없음 · 보안·프라이버시 · 원문 상태 Draft · 2026-06-03 작성
양자내성 서명과 STARK 증명을 블록에 그대로 싣는 대신, 멤풀에서 재귀 STARK 하나로 묶어 블록 헤더에 담는 EIP-8141 프레임 모드를 추가합니다.
왜 필요한가
양자컴퓨터에도 안전한 해시 기반 서명은 하나가 약 2~3kB이고 검증에 15만~20만 가스가 듭니다. 격자 기반 서명도 비용이 비슷합니다. 해시 기반 영지식 증명인 STARK(Scalable Transparent ARguments of Knowledge)는 128kB가 넘고 사용자 기기에서 빨리 만들려면 512kB까지 커져 검증에 수백만 가스가 필요합니다. 이런 데이터를 트랜잭션에 그대로 실으면 프라이버시 프로토콜은 쓸 수 없을 만큼 비싸지고 포함 목록 제도인 FOCIL(EIP-7805)이나 프레임 트랜잭션(EIP-8141)과는 아예 맞지 않습니다. 이 EIP는 트랜잭션에는 가벼운 선언만 남기고 실제 서명과 증명은 멤풀이 검증한 뒤 재귀 STARK 하나로 합쳐 블록이 그 증명 하나만 들고 다니게 해서 이 문제를 풉니다.
무엇이 바뀌나
지금
- 양자내성 서명 하나가 약 2~3kB, 검증에 15만~20만 가스가 듭니다
- STARK 증명은 128kB에서 512kB에 달해 수백만 가스가 필요합니다
- 서명과 증명 데이터가 블록에 그대로 실려 모든 검증 노드가 비용을 집니다
EIP-8288 이후
- 트랜잭션은 (scheme, data_hash, verification_key_hash) 세 값짜리 가벼운 의존성 선언만 싣습니다
- 실제 서명과 증명은 멤풀에서 검증되고 재귀 STARK 하나로 합쳐집니다
- 블록 헤더의 recursive_stark 하나가 블록 안 모든 의존성의 유효성을 증명합니다
- leanSPHINCS 서명 검증은 3,000가스, STARK는 30,000가스로 책정됩니다
누구에게 영향이 있나
- 사용자·지갑: 양자내성 서명이나 영지식 증명을 쓰는 트랜잭션을 현실적인 가스 비용으로 보낼 수 있습니다.
- 멤풀 노드: 래퍼 객체를 검증하고 1,000밀리초마다 재귀 STARK를 새로 만들어 전달하는 집계 역할이 생깁니다.
- 빌더·FOCIL 생성자: 받은 증명들을 같은 형식의 재귀 STARK로 다시 감싸 블록이나 포함 목록에 싣습니다. STARK 관련 오버헤드는 집계 주기당 약 256kB로 고정됩니다.
- 클라이언트 팀: 블록 헤더에 recursive_stark 필드가 추가되는 합의 변경이어서 네트워크 업그레이드로 활성화해야 합니다.
심층 설명
의존성 검증 프레임(DEP_VERIFY_FRAME_MODE = 4)
EIP-8141 프레임 모드에 DEP_VERIFY_FRAME_MODE(값 4)를 추가합니다. 이 프레임은 EVM 코드로 실행되지 않고 (scheme, data_hash, verification_key_hash) 트리플을 의존성으로 선언합니다. data는 정확히 96*k 바이트로, 각 96바이트는 31바이트 0 패딩과 scheme 1바이트, data_hash 32바이트, verification_key_hash 32바이트입니다. 현재 scheme은 LEANSPHINCS_SCHEME(0x10)만 유효하고 LEANSTARK_SCHEME(0x11)은 get_deps_hash가 정의될 때까지 예약 상태입니다. 트리플 수는 1 이상 MAX_DEPENDENCIES_PER_FRAME(256) 이하, target은 None, value와 flags는 0이어야 하고 원자적 배치(atomic batch)의 구성원이 될 수 없습니다. limits.execution은 트리플별 검증 가스의 합과 정확히 같아야 하고 limits.state는 0입니다. 영수증은 status = 1, gas_used.state = 0, 로그 없음으로 남는데, 프레임 하나를 빼면 뒤 프레임들의 인덱스가 밀려 FRAMEPARAM 조회가 어긋나기 때문에 실행하지 않는 프레임에도 영수증을 남깁니다.
트랜잭션 의존성과 0 data_hash 규약
트랜잭션의 의존성 목록은 모든 의존성 검증 프레임의 트리플을 모아 deduplicate_and_sort로 정렬·중복 제거한 것입니다. data_hash가 32바이트 0이면 그 트랜잭션 자신의 서명 해시 compute_sig_hash(tx)를 뜻합니다. 서명 해시가 프레임 data를 덮기 때문에 트랜잭션이 자기 서명 해시를 직접 실을 수 없어서 이런 자리표시 규약을 둡니다. 프레임의 data 자체는 바뀌지 않아 compute_sig_hash는 0 바이트를 그대로 덮고 FRAMEDATACOPY도 0을 돌려줍니다. 실행 중에는 FRAMEPARAM(0x02, i)로 프레임 모드를, FRAMEPARAM(0x04, i)로 data 길이를 읽고 FRAMEDATACOPY로 트리플을 복사해 컨트랙트가 선언된 의존성을 들여다볼 수 있습니다.
블록 유효성: recursive_stark 헤더 필드
블록 헤더에 recursive_stark = [stark_proof, block_deps_hash] 필드가 추가됩니다. block_deps_hash는 블록 내 모든 트랜잭션 의존성의 합집합에 대한 get_deps_hash(dependencies(block))이고 증명이 공개 입력으로 약속하는 다이제스트입니다. 블록이 유효하려면 이 해시가 맞아야 합니다. 의존성이 비어 있으면 stark_proof도 비어 있어야 하며 그렇지 않으면 증명이 고정된 프로토콜 수준 검증 키 AGGREGATED_VK에 대해 검증돼야 합니다. 재귀 STARK 회로는 직접 의존성을 leanSPHINCS·leanSTARK 검증기로 확인하고 내부 재귀 증명들을 검증해 의존성을 합친 뒤, discard 집합과 중복을 제거한 결과의 해시가 공개 입력 deps_hash와 같음을 증명합니다. 무제한 깊이 재귀를 위해 AGGREGATED_VK 자체를 증명의 입력으로 넣습니다. 회로는 트랜잭션이나 블록 구조를 모르고 평평한 트리플 목록만 봅니다.
멤풀 래퍼와 재귀 집계
멤풀에서는 트랜잭션을 [transactions, mode, content] 래퍼로 감싸 AGGREGATION_INTERVAL(1,000밀리초)마다 브로드캐스트합니다. mode 0은 의존성별 개별 증명을 싣고 mode 1은 전체를 증명하는 재귀 STARK 하나를 싣습니다. 두 모드 모두 leanSPHINCS 의존성 16개(MAX_LEANSIG_DEPS_PER_WRAPPER), leanSTARK 의존성 1개(MAX_LEANSTARK_DEPS_PER_WRAPPER) 한도와, deps가 전체 트랜잭션 의존성의 정렬·중복 제거된 합집합이라는 조건을 검증합니다. 멤풀 노드는 받은 래퍼를 검증해 수락하고 매 주기마다 유효한 트랜잭션 전부를 담은 mode 1 래퍼를 새로 만들어 전달하며 이미 보낸 트랜잭션은 해시로 대체합니다. 증명 시간이 부족하면 자기 직전 라운드 집계, 제거할 항목 반영, 새 트랜잭션을 많이 더하는 타 노드 집계 순, 우선순위 수수료 순의 사용자 트랜잭션 순서로 우선 처리합니다. STARK 없이 leanSPHINCS만 있는 풀이라면 서명 100개 정도까지는 그냥 이어 붙인 mode 0 재전파가 더 공간 효율적일 수 있습니다.
가스 계산
의존성 검증 프레임의 limits.execution은 트리플별로 LEANSPHINCS_VERIFICATION_GAS(3,000) 또는 LEANSTARK_VERIFICATION_GAS(30,000)를 더한 값입니다. 실제 STARK 검증은 빌더가 오프체인에서 하므로 이 가스는 기대 비용이고 모든 검증 노드가 아니라 빌더와 멤풀만 비용을 지기 때문에 온체인 검증보다 훨씬 쌉니다. 여기에 트랜잭션마다 recursive_stark_gas(tx) = LEANSTARK_VERIFICATION_GAS * 중복 포함 트리플 수가 고유 가스(intrinsic gas)에 더해져 트랜잭션과 블록의 gas_used에 들어갑니다. 의존성은 트랜잭션 본문 수준에 있어 실행이 되돌려져도(revert) 영향받지 않고 가스는 전부 청구됩니다. 같은 의존성을 여러 번 선언하는 것은 합법이지만 선언마다 과금되므로 낭비입니다. 고정 가스는 leanSPHINCS와 STARK 각 한 가지 파라미터를 전제한 것이고 k회용 서명 혼용이나 증명 크기별 트레이드오프가 생기면 가변 비용으로 바뀔 수 있다고 적고 있습니다.
FOCIL 호환
FOCIL(EIP-7805) 데이터 구조가 [transactions, recursive_stark]로 확장돼 포함 목록도 블록처럼 자기 트랜잭션들의 의존성 증명을 함께 들고 다닙니다. 어테스터는 FOCIL 내 재귀 증명을 검증해 어떤 트랜잭션이 포함 의무 대상인지 판단합니다. 빌더는 FOCIL과 멤풀 래퍼를 같은 방식으로 처리합니다. 의존성과 증명을 추출하고 포함할 트랜잭션을 정한 뒤 미포함 트랜잭션의 의존성을 뺀 합집합에 대한 재귀 STARK를 새로 만들어 헤더에 넣습니다. 멤풀 재전파, FOCIL 생성, 블록 빌딩은 설계상 정확히 같은 집계 작업입니다. 멤풀 노드는 트랜잭션 의미를 몰라도 증명을 재귀 집계할 수 있고 피어당 대역폭 오버헤드는 트랜잭션 수와 무관하게 상수라서 FOCIL의 검열 저항성이 유지됩니다.
신뢰 가정과 DoS 방어
보안은 Lean Ethereum 회로의 건전성, deps_hash에 쓰는 해시 함수(현재 툴링은 BLAKE2s, BLAKE3가 유력한 교체 후보이고 헤더와 회로가 함께 바뀜), 그리고 재귀 STARK의 건전성에 기댑니다. 재귀 증명의 건전성은 널리 참으로 여겨지고 이미 온체인에서 쓰이지만 전 과정 형식 증명을 어렵게 만들고 사용자가 넣는 검증 키의 재귀 깊이는 무제한일 수 있습니다. DoS 방어는 트랜잭션당 leanSPHINCS 의존성 16개(MAX_SIGS_PER_TX)와 leanSTARK 1개(MAX_STARKS_PER_TX), 프레임당 256개, 래퍼당 한도, 의존성 수에 비례하는 가스로 이뤄집니다. 한도는 같은 데이터를 calldata로 그대로 보냈을 때와 최악의 멤풀 부하가 같도록 잡았지만 양자내성 서명과 증명 자체가 기존 타원곡선 방식보다 크고 비싸서 멤풀 DoS 노출 증가는 여전히 남습니다. 한도 설계는 ERC-7562의 멤풀 정책 틀을 참고했습니다.
현재 상태
이 EIP는 Draft 상태라 상수(AGGREGATED_VK, DEPS_HASH는 아직 TBD)와 명세가 앞으로 바뀔 수 있습니다. 2026년 9월 16일 AMA #15에서 논의됐으나 결정은 없었고 특정 포크에 포함하기로 한 결정도 아직 없습니다.