EIP-1559 수수료 시장 개편 (기본 수수료 도입) (Fee market change for ETH 1.0 chain)
최종 확정 · 수수료·가스 · 원문 상태 Final · 2019-04-13 작성
경매로 정하던 거래 수수료를 프로토콜이 블록마다 계산하는 기본 수수료(base fee)로 바꾸고 그 기본 수수료를 소각합니다. 블록 크기도 수요에 따라 목표치의 두 배까지 늘어납니다.
왜 필요한가
이전 이더리움은 사용자가 가스 가격을 직접 부르고 채굴자가 높은 값부터 담는 단순 경매로 수수료를 정했습니다. 이 방식에는 네 가지 문제가 있었습니다. 첫째, 거래 하나를 더 담는 실제 비용은 거의 같은데 수수료는 열 배씩 출렁였습니다. 둘째, 블록 크기가 고정이라 수요가 잠깐 몰리면 거래가 여러 블록을 기다렸습니다. 셋째, 부른 값을 그대로 내는 경매(first price auction)는 비효율이 커서 복잡한 수수료 추정 알고리즘이 필요했고 그래도 과다 지불이 잦았습니다. 넷째, 발행량이 없는 블록체인은 수수료만으로 채굴자를 보상할 때 불안정해지는 문제가 알려져 있습니다. 이 제안은 네트워크 혼잡도에 따라 프로토콜이 기본 수수료를 조금씩 올리고 내리게 해서 지갑이 수수료를 믿을 만하게 자동 설정할 수 있게 합니다.
무엇이 바뀌나
지금
- 사용자가 가스 가격을 직접 불러 경쟁하고 부른 만큼 전액 냅니다
- 수수료 예측이 어려워 과다 지불이 자주 생깁니다
- 블록 크기가 고정이라 수요가 몰리면 거래가 여러 블록을 기다립니다
- 수수료 전액이 채굴자에게 갑니다
EIP-1559 이후
- 프로토콜이 블록마다 기본 수수료를 정하고 지갑이 자동으로 맞춥니다
- 블록 간 기본 수수료 변동 폭이 제한되어 예측이 쉬워집니다
- 블록이 목표 가스 사용량의 두 배까지 늘어나 수요 급증을 흡수합니다
- 기본 수수료는 소각되고 채굴자는 우선 수수료(priority fee)만 받습니다
누구에게 영향이 있나
- 사용자: 지갑이 기본 수수료를 추정해 자동 설정하므로, 혼잡한 시기에도 대부분 수수료를 손으로 조정할 필요가 없어집니다. 최대 수수료(max fee)로 총비용 상한도 걸 수 있습니다.
- 지갑·앱 개발자: 새 타입 2 트랜잭션 형식을 지원하고 경매용 수수료 추정 로직을 기본 수수료 기반으로 바꿔야 합니다. 블록 해시 계산에 쓰는 헤더 구조도 항목이 하나 늘어납니다.
- 채굴자(블록 생산자): 기본 수수료는 받지 못하고 우선 수수료와 블록 보상만 받습니다. 수수료를 올리려고 기본 수수료를 조작할 유인이 사라집니다.
- 클라이언트 팀: 최대 블록 크기가 커지므로 최대 크기 블록을 메모리 부족 같은 오류 없이 처리할 수 있어야 합니다.
심층 설명
타입 2 트랜잭션 형식과 서명
FORK_BLOCK_NUMBER부터 EIP-2718 TransactionType 2가 도입됩니다. TransactionPayload는 rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])이고 전체 형식은 0x02 || rlp([...])입니다. 서명은 keccak256(0x02 || rlp([서명 제외 9개 항목]))에 대한 secp256k1 서명입니다. 기본 비용(intrinsic cost)은 EIP-2930을 이어받아 21000 + 16 * 0이 아닌 calldata 바이트 + 4 * 0인 calldata 바이트 + 1900 * 접근 목록 스토리지 키 수 + 2400 * 접근 목록 주소 수입니다. ReceiptPayload는 rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])입니다.
기본 수수료 조정 공식
블록 헤더에 base_fee_per_gas 필드가 추가됩니다. 가스 목표치(gas target)는 블록 가스 한도를 ELASTICITY_MULTIPLIER(2)로 나눈 값입니다. 부모 블록의 가스 사용량이 목표치와 같으면 기본 수수료가 그대로 유지되고 목표치를 넘으면 parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR(8)만큼(최소 1) 오르며 목표치에 못 미치면 같은 공식으로 내립니다. 포크 블록에서는 기본 수수료가 INITIAL_BASE_FEE(1000000000)로 시작하고 가스 목표치가 부당하게 반 토막 나지 않도록 부모의 gas_limit을 그대로 목표치로 씁니다. 블록 가스 한도의 블록당 변경 폭은 부모 한도의 1/1024 미만으로 제한되고 최소 한도는 5000입니다.
수수료 정산과 소각
유효한 거래는 max_fee_per_gas >= block.base_fee_per_gas, max_fee_per_gas >= max_priority_fee_per_gas를 만족해야 하고 서명자 잔액이 gas_limit * max_fee_per_gas 이상이어야 합니다. 실제 팁은 priority_fee_per_gas = min(max_priority_fee_per_gas, max_fee_per_gas - block.base_fee_per_gas)로 정해지고 사용자가 내는 가스당 가격은 effective_gas_price = priority_fee_per_gas + block.base_fee_per_gas입니다. 쓰지 않은 가스는 effective_gas_price 기준으로 환불됩니다. 블록 생산자는 gas_used * priority_fee_per_gas만 받고 기본 수수료 몫은 누구에게도 지급되지 않고 소각됩니다. 생산자가 기본 수수료를 받지 못하게 한 것은 수수료를 더 걷으려고 기본 수수료를 조작할 유인을 없애기 위해서입니다.
GASPRICE 옵코드와 블록 해시 변화
GASPRICE(0x3a) 옵코드는 effective_gas_price를 반환해야 합니다. 이전에는 이 값이 서명자가 내는 가스당 ETH와 채굴자가 받는 가스당 ETH를 동시에 뜻했지만 이 변경 이후에는 서명자가 내는 금액만 뜻하고 채굴자가 받은 금액은 EVM 안에서 직접 알 수 없게 됩니다. 또 블록 해시 계산에 들어가는 자료 구조에 항목이 하나(base_fee_per_gas) 추가되므로, 헤더를 구성 요소에서 조립하는 애플리케이션은 새 항목을 끝에 넣어야 합니다. 헤더 바이트를 그대로 해시하는 경우는 그대로 동작합니다.
레거시 트랜잭션 호환
기존 형식의 거래도 계속 동작하고 블록에 포함됩니다. 처리할 때는 gas_price가 max_fee_per_gas와 max_priority_fee_per_gas 양쪽 값으로 정규화됩니다. 그래서 레거시 거래의 gas_price는 기본 수수료와 팁으로 전부 소진되며 새 가격 체계의 이점(총비용 상한과 팁을 따로 정하는 것)을 직접 누리지는 못합니다. EIP-2930 타입 1 거래도 같은 방식으로 gas_price가 두 필드로 정규화됩니다.
보안 고려사항
최대 블록 크기가 커지므로 단기 급증 블록을 클라이언트가 안정적으로 처리해야 합니다. 평균 블록 크기는 장기적으로 이전과 비슷하게 유지될 것으로 원문은 봅니다. 거래 순서는 팁 경쟁이 줄어 클라이언트 내부 구현에 좌우되는데, 스팸 공격을 막기 위해 같은 팁이면 수신 시각순 정렬이 권장됩니다. 채굴자들이 기본 수수료를 떨어뜨리려고 빈 블록을 캐는 담합 공격은 이탈자가 더 이득을 보는 구조라서, 이론상 수익을 내려면 해시파워 50% 초과가 필요하고 그 경우 이중 지불이 더 수익성이 높아 비현실적이라고 분석합니다. 공격이 시도되면 탄력 계수(현재 2배)를 올리는 대응도 가능합니다. 또 기본 수수료 소각으로 ETH 공급량 고정을 보장할 수 없게 되어, 소각량과 채굴 보상의 크기에 따라 디플레이션 또는 인플레이션이 될 수 있습니다.