EIP-8037 상태 생성 가스 비용 인상 (State Creation Gas Cost Increase)

포함 제외 (DFI) · 수수료·가스 · 원문 상태 Last Call · 2025-10-01 작성

새 계정, 새 저장 슬롯, 컨트랙트 코드처럼 이더리움 상태를 늘리는 작업의 가스 비용을 상태 1바이트당 1530가스 기준으로 통일해 올리고 이 비용을 실행 가스와 분리해 따로 셉니다.

왜 필요한가

이더리움 노드는 모든 계정과 저장 데이터를 '상태(state)'라는 데이터베이스에 보관합니다. 블록 가스 한도를 올리면 거래를 더 많이 처리할 수 있지만 상태도 그만큼 빨리 불어납니다. 원문에 따르면 2026년 1월 기준 Geth 노드의 상태 데이터베이스는 약 390 GiB이고, 가스 한도가 30M에서 60M으로 오른 뒤 하루에 새로 생기는 상태가 약 105 MiB에서 약 326 MiB로 세 배 넘게 늘어 연간 약 116 GiB씩 커지고 있습니다. 200M 한도에서는 연간 약 387 GiB가 늘어 노드 성능이 떨어지기 시작하는 650 GiB 선을 1년 안에 넘게 됩니다. 게다가 지금은 같은 크기의 상태를 만들어도 방법에 따라 비용이 다릅니다. 컨트랙트 배포는 바이트당 약 200가스인데 저장 슬롯은 바이트당 약 313가스이고, 이미 있는 코드를 또 배포해도 클라이언트는 중복 저장하지 않는데 비용은 같습니다. 이 제안은 상태 1바이트당 비용을 하나로 정해 모든 상태 생성 작업에 같은 잣대를 적용하고 상태 생성 비용을 따로 세어 블록 가스 한도를 더 올릴 수 있게 합니다.

무엇이 바뀌나

지금

EIP-8037 이후

누구에게 영향이 있나

심층 설명

바이트당 비용 CPSB 1530은 어떻게 나왔나

CPSB는 기준 블록 가스 한도 150M에서 연간 상태 증가를 120 GiB(128,849,018,880바이트)로 맞추도록 정한 상수입니다. 슬롯 시간 12초로 1년에 2,628,000블록이 나오고, 다차원 계량에서는 기본 수수료가 목표치(한도의 절반)로 수렴하므로 블록 가스의 50%를 상태 가스에 쓸 수 있다고 가정합니다. 그러면 1년에 쓸 수 있는 상태 가스는 75,000,000 x 2,628,000 = 1.971 x 10^14이고, 이를 목표 바이트 수로 나누면 약 1530가스/바이트가 나옵니다. 150M은 현재 60M과 예상되는 300M 사이의 중간값으로, 비용을 한 번에 너무 올리지도 않고 나중에 다시 크게 올릴 필요도 없게 고른 값입니다. 블록이 상태 생성으로만 꽉 차는 최악의 경우 상태 증가는 100M에서 80 GiB, 150M에서 120 GiB, 200M에서 160 GiB, 300M에서 240 GiB입니다. 가스 한도가 크게 바뀌어 예상 증가율이 달라지면 후속 EIP로 CPSB를 다시 유도할 수 있습니다.

새 파라미터와 바뀌는 비용

새 파라미터는 CPSB 1530, STATE_BYTES_PER_STORAGE_SET 64, STATE_BYTES_PER_NEW_ACCOUNT 120, STATE_BYTES_PER_AUTH_BASE 23, SYSTEM_MAX_SSTORES_PER_CALL 16, TX_MAX_TOTAL_GAS_LIMIT 4,294,967,295(2^32 - 1)입니다. 바이트 수는 디스크에 실제로 쓰이는 크기에서 나왔습니다. 새 계정은 키 해시 32 + 논스 8 + 잔액 16 + 코드 해시 32 + 저장 루트 32로 120바이트, 새 저장 슬롯은 키 해시 32 + 값 32로 64바이트, EIP-7702 위임 표시는 0xef0100 3바이트 + 주소 20바이트로 23바이트입니다. 이에 따라 GAS_CREATE(32,000), GAS_NEW_ACCOUNT(25,000), PER_EMPTY_ACCOUNT_COST(25,000)는 120 x CPSB, GAS_STORAGE_SET(20,000)은 64 x CPSB, GAS_CODE_DEPOSIT(바이트당 200)은 바이트당 CPSB, PER_AUTH_BASE_COST(12,500)는 23 x CPSB의 상태 가스가 됩니다. 여기에 EIP-8038이 정하는 CREATE_ACCESS, ACCOUNT_WRITE, 코드 해시 비용 6 x ceil(len/32), EXECUTION_PER_AUTH_BASE_COST 같은 실행 가스가 따로 붙습니다. EXECUTION_PER_AUTH_BASE_COST는 calldata 1,616(101바이트 x 16) + PRECOMPILE_ECRECOVER + COLD_ACCOUNT_ACCESS + 2 x WARM_ACCESS의 합입니다. EIP-8038 쪽 값은 아직 확정되지 않았습니다.

두 가스 차원과 저수지 모델

가스는 실행 가스(execution-gas)와 상태 가스(state-gas) 두 차원으로 나뉩니다. 거래에는 가스 한도 값이 tx.gas 하나뿐이므로 저수지(reservoir) 모델로 둘을 나눕니다. 사전 실행 단계에서 evm_gas = tx.gas - intrinsic_gas, execution_gas_budget = TX_MAX_GAS_LIMIT - intrinsic_gas로 두고, gas_left = min(execution_gas_budget, evm_gas), state_gas_reservoir = evm_gas - gas_left로 초기화합니다. 즉 EIP-7825 한도를 넘는 가스가 저수지에 들어갑니다. 실행 가스는 gas_left에서만 빠지고 상태 가스는 저수지에서 먼저 빠지다가 바닥나면 gas_left에서 빠지면서 state_gas_from_gas_left를 늘립니다. 되돌릴 때는 반대 순서(LIFO)로 gas_left부터 채웁니다. 새 카운터는 evm_state_gas_used(거래의 총 상태 가스), state_gas_from_gas_left(프레임별, gas_left에서 빌린 상태 가스), state_gas_baseline(프레임 진입 시 저수지 값), state_gas_committed(최상위 프레임만 사용, 되돌리면 안 되는 몫) 넷입니다. 저수지는 자식 프레임에 전부 넘어가고 63/64 규칙은 gas_left에만 적용됩니다. GAS 명령어는 gas_left만 돌려주며 SSTORE의 GAS_CALL_STIPEND 검사도 gas_left만 봅니다.

SSTORE, 계정 생성, SELFDESTRUCT의 상태 가스 규칙

SSTORE는 거래 시작 시점의 원래 값을 기준으로 봅니다. 원래 0이던 슬롯에 0이 아닌 값을 쓰면 64 x CPSB를 상태 가스로 떼고 원래 0이던 슬롯을 다시 0으로 지우면 같은 양을 되돌려 채웁니다. 원래 값이 0이 아니던 슬롯은 어떻게 바꿔도 상태 가스 조정이 없습니다. 계정 생성 비용은 조건부로 뗍니다. 값이 있는 CALL*이 존재하지 않는 계정으로 가면 자식 프레임 직전에 120 x CPSB를 떼고 프레임 진입 전에 실패하거나 자식이 revert·예외 정지하면 되돌려 채웁니다. CREATE/CREATE2는 EIP-7928에 따라 잔액·논스·깊이 검사를 통과한 뒤에야 목적지 주소를 읽는데, 이 한 번의 읽기가 EIP-684 충돌 검사를 겸합니다. 목적지가 없으면 63/64 분배 전에 생성 프레임에서 120 x CPSB를 떼고 잔액만 있는 기존 주소면 떼지 않습니다. 코드 저장 비용 L x CPSB는 평소처럼 코드 저장 시점에 뗍니다. 여기서 존재하는 계정은 EIP-161 기준으로 논스나 잔액이 0이 아니거나 코드가 있는 계정입니다. SELFDESTRUCT는 같은 거래에서 만든 계정을 지워도, 이전부터 있던 계정의 잔액만 옮겨도 상태 가스를 되돌려 주지 않습니다. EIP-6780과 같은 방향입니다.

revert·예외 정지와 프레임 병합

프레임이 revert하거나 예외로 멈추면 상태 가스를 되돌려 채우는 대신 기준값으로 복원합니다. net_state_gas = state_gas_baseline - state_gas_reservoir + state_gas_from_gas_left를 evm_state_gas_used에서 빼고, state_gas_from_gas_left를 gas_left에 더한 뒤 0으로 만들고, 저수지를 기준값으로 되돌립니다. revert면 복원된 gas_left가 부모에게 돌아가고 예외 정지면 gas_left가 0으로 소모됩니다. 최상위 프레임만 기준값이 진입 시점과 다를 수 있는데 EIP-7702 권한 부여가 있을 때입니다. 사전 실행 단계에서 적용된 권한 부여는 최상위 프레임이 revert해도 취소되지 않으므로 그 상태 가스는 state_gas_committed로 묶어 되돌리지 않고, 기준값은 권한 부여 비용 뒤 거래 대상의 계정 생성 비용 앞에서 잡습니다. 자식 프레임이 성공하면 남은 gas_left와 state_gas_from_gas_left를 부모에 합치고, d = min(state_gas_reservoir, state_gas_from_gas_left)만큼 저수지에서 gas_left로 옮깁니다. SSTORE의 원래 값이 거래 시작 기준이라 한 프레임에서 뗀 상태 가스가 다른 프레임에서 되돌아올 수 있기 때문입니다. 이 이동은 상태 생성을 취소하는 것이 아니므로 evm_state_gas_used는 바뀌지 않습니다.

거래 가스 사용량, 블록 집계, 영수증

거래가 끝나면 tx_gas_used_before_refund = tx.gas - gas_left - state_gas_reservoir로 계산하고, 환급은 사용량의 20%(// 5)까지 그대로 둡니다. 그 뒤 EIP-7623의 calldata 하한(calldata_floor_gas_cost)을 max로 적용한 값이 tx_gas_used이며 영수증의 cumulative_gas_used에 들어갑니다. 블록 수준에서는 카운터가 둘입니다. tx_state_gas = evm_state_gas_used이고, tx_execution_gas = max(tx_gas_used_after_refund - tx_state_gas, calldata_floor_gas_cost)입니다. calldata 하한을 실행 가스 쪽에만 비교하는 이유는 상태 생성으로 채운 거래가 calldata를 하한보다 싸게 블록에 넣는 것을 막기 위해서입니다. 그래서 두 차원에 집계된 합이 보낸 사람이 낸 가스보다 클 수 있는데 이는 의도된 것입니다. 블록 헤더의 gas_used는 max(block_execution_gas_used, block_state_gas_used)이고, 이 값이 block.gas_limit 이하여야 하며 기본 수수료 갱신의 gas_used_delta에도 쓰입니다. 상태 가스 되돌림은 EIP-7778이 말하는 환급과 달리 실제로 만들어지지 않은 상태에 대한 것이므로 EIP-7778과 함께 적용해도 evm_state_gas_used에 그대로 반영되고 실행 가스 쪽만 환급 전 값으로 바뀝니다.

시스템 콜, 하위 호환, 보안 고려

블록 시작마다 호출되는 시스템 컨트랙트(EIP-2935, 4788, 7002, 7251)의 가스 한도는 30M에서 30,000,000 + 64 x 1530 x 16으로 늘어나고, 늘어난 몫은 state_gas_reservoir에 들어갑니다. 시스템 콜은 EIP-7825 한도와 블록 가스 한도의 영향을 받지 않고 블록 카운터에도 더하지 않습니다. 하위 호환 면에서는 되돌림이 gas_left부터 채워지므로 한 프레임 안에서도, 하위 호출을 사이에 두고도 GAS 값이 작업 전보다 커질 수 있습니다. SSTORE(k, 1); GAS; SSTORE(k, 0); GAS 순서면 두 GAS 값의 차이가 음수가 됩니다. 이미 배포된 컨트랙트가 이런 방식으로 가스를 재면 고칠 수 없습니다. ERC-4337 EntryPoint처럼 gasleft() 차이로 하위 호출 소비량을 재는 번들러는 저수지에서 빠진 상태 가스를 볼 수 없으므로 상태 가스를 명시적으로 계산해야 합니다. Nick's method 팩토리처럼 100,000가스 한도가 박힌 미리 서명된 배포 거래는 새 네트워크에서 실패하므로 제네시스에 미리 배포하거나 거래를 다시 만들어야 합니다. 새 계정 생성 183,600과 단순 송금 21,000의 차이를 노려 먼저 송금으로 계정을 만드는 우회는 EIP-2780이 값이 있는 송금의 고유 가스에 계정 생성 비용을 더해 막습니다. 블록 빌더는 두 차원을 함께 보며 채워야 하지만 한 차원이 찰 때까지 채우는 단순한 방식도 대부분 충분하다고 봅니다.

문서 상태와 코어 개발자 콜 결정

원문 상태는 Last Call이고 마감은 2026-11-01입니다. 코어 개발자 콜에서는 07.13 ACDT #87에서 블록을 예상 최대치의 8배까지 부풀릴 수 있던 플로어 코스트(floor cost) 버그 수정을 데브넷7에 포함했고 'regular gas'를 'execution gas'로 바꾸는 용어 정리를 07.27 ACDT #89에서 반대 없이 데브넷8에 넣기로 했습니다. 08.13 ACDE #243에서는 가스 재조정 수치가 최종 확정되고 글램스테르담(Glamsterdam)의 200M 가스 한도가 확인됐습니다. 09.03 ACDC #186에서는 크로스 프레임 상태 가스 버그 수정이 승인돼 모든 EL 클라이언트가 DevNet 8에 배포하기로 했고 09.14 ACDT #96에서는 총 상태 가스 한도를 명시하는 PR EIPs#12311이 병합됐습니다. 반면 SELFDESTRUCT 상태 가스 환급을 되살리자는 요청(EIPs PR #12249)은 08.27 ACDE #244에서 글램스테르담에 넣지 않고 헤고타에서 다루기로 보류했고, 08.31 ACDT #94에서 구현 복잡도와 셀프디스트럭트 폐기 방향을 이유로 포함하지 않기로 했으며 09.07 ACDT #95에서 PR을 닫기로 했습니다. 이 결정으로 임시 생성과 셀프디스트럭트를 한 거래에서 쓰는 패턴은 상태를 늘리지 않아도 상태 가스를 냅니다.

EIP 원문 · ← EIPs