Gas in Ethereum
이더리움에서 모든 연산은 공짜가 아니다. 스마트 컨트랙트 실행, 토큰 전송, NFT 민팅 등 모든 작업에는 Gas 라는 비용이 발생한다.
Gas 란 무엇인가
Gas 는 이더리움에서 연산의 비용을 측정하는 단위이다. 마치 자동차가 거리를 이동하는 데 연료가 필요하듯, EVM 에서 실행되는 모든 연산에는 Gas 가 소비된다.
모든 EVM 연산(opcode)에는 정해진 Gas 비용이 있다.
덧셈 연산은 3 Gas, 곱셈은 5 Gas, 스토리지에 데이터를 쓰는 작업은 20,000 Gas 이상이 소비된다.
이러한 비용 체계는 Yellow Paper에 명시되어 있으며, 하드포크를 통해 조정될 수 있다.
Gas가 필요한 이유
Gas 메커니즘이 없다면 이더리움 네트워크는 무너진다. 세 가지 핵심 문제를 해결하기 위해 Gas가 존재한다.
1. 무한 루프 방지 (Halting Problem)
while(true) {
// 무한 루프
}
위와 같은 코드가 Gas 제한 없이 실행된다면 이더리움 노드는 영원히 멈춘다.
Gas Limit이 존재하므로, 연산이 일정량 이상 소비되면 트랜잭션은 자동으로 중단된다.
2. 네트워크 자원의 공정한 사용
블록체인은 전 세계 수천 개의 노드가 동일한 연산을 반복 실행하는 구조이다.
복잡한 연산을 실행하는 사용자가 더 많은 비용을 지불해야 공정하다.
Gas는 “연산량”을 정확히 측정하여 비용을 부과한다.
3. 스팸 방지
Gas가 없다면 공격자는 무료로 수백만 개의 트랜잭션을 보내 네트워크를 마비시킬 수 있다.
Gas는 경제적 비용을 부과하여 스팸 공격의 비용을 기하급수적으로 증가시킨다.
Gas와 ETH의 관계
Gas는 ETH와 별개의 개념이다. 혼동하기 쉽지만 명확히 구분해야 한다.
-
Gas: 연산의 “양”을 나타내는 추상적 단위. “이 트랜잭션은 50,000 Gas를 소비한다”
-
ETH: 그 “양”에 대한 “가격”을 지불하는 화폐. “1 Gas당 30 gwei를 지불하겠다”
Gas는 연산의 복잡도를 나타내는 불변의 값이고, ETH는 그 연산을 실행하기 위해 지불하는 변동 가격이다. 같은 트랜잭션이라도 네트워크 혼잡도에 따라 ETH 비용은 달라지지만, Gas 소비량은 동일하다.
Gas 가 사용되는 곳
이더리움에서 가장 단순한 작업인 ETH 전송조차 21,000 Gas를 소비한다. 이는 트랜잭션의 서명 검증, 논스(nonce) 확인, 잔액 업데이트 등 기본적인 처리 비용이다.
EVM Opcode별 Gas 비용
EVM은 200개 이상의 opcode를 지원하며, 각각 고유한 Gas 비용이 책정되어 있다. 연산의 복잡도와 네트워크 부담에 비례하여 비용이 결정된다.
산술 연산
-
ADD (덧셈): 3 Gas
-
MUL (곱셈): 5 Gas
-
DIV (나눗셈): 5 Gas
-
EXP (지수): 10 Gas + 지수 크기에 따른 추가 비용
-
ADDMOD, MULMOD (모듈러 연산): 8 Gas
메모리 연산
-
MLOAD (메모리 읽기): 3 Gas
-
MSTORE (메모리 쓰기): 3 Gas
-
MSTORE8 (1바이트 쓰기): 3 Gas
메모리 연산은 저렴하다. 메모리는 트랜잭션 실행 동안만 존재하고 블록체인에 영구 저장되지 않기 때문이다.
스토리지 연산 (가장 비싼 연산)
-
SSTORE (스토리지 쓰기): 20,000 Gas (새로운 슬롯에 쓰기)
-
SSTORE (기존 값 업데이트): 5,000 Gas
-
SSTORE (0으로 설정, 스토리지 삭제): 5,000 Gas 소비 후 15,000 Gas 환불
-
SLOAD (스토리지 읽기): 2,100 Gas (cold access), 100 Gas (warm access)
스토리지는 블록체인의 상태(state)에 영구적으로 기록된다.
전 세계 모든 풀노드가 이 데이터를 저장하고 동기화해야 하므로, 비용이 메모리 연산의 수백 배에 달한다.
컨트랙트 관련 연산
-
CREATE (컨트랙트 생성): 32,000 Gas
-
CREATE2 (결정론적 주소로 컨트랙트 생성): 32,000 Gas
-
CALL (다른 컨트랙트 호출): 700 Gas (warm), 2,600 Gas (cold)
-
DELEGATECALL: 700 Gas (warm), 2,600 Gas (cold)
-
STATICCALL: 700 Gas (warm), 2,600 Gas (cold)
-
SELFDESTRUCT (컨트랙트 제거): 5,000 Gas + 상황에 따른 추가 비용
로그 이벤트
-
LOG0: 375 Gas + 8 Gas × 데이터 바이트 수
-
LOG1 (토픽 1개): 750 Gas + 8 Gas × 데이터 바이트 수
-
LOG2 (토픽 2개): 1,125 Gas + 8 Gas × 데이터 바이트 수
-
LOG3, LOG4: 토픽 수에 비례하여 375 Gas씩 추가
이벤트는 블록체인 상태에 저장되지 않고 트랜잭션 receipt에만 기록되므로 비교적 저렴하다.
하지만 데이터 크기가 크면 비용이 급증한다.
Gas, GasPrice, GasLimit
이더리움 초보자가 가장 혼동하는 개념이 Gas, GasPrice, GasLimit의 차이이다. 세 가지는 완전히 다른 의미를 가진다.
Gas: 연산의 단위
Gas는 “이 작업이 얼마나 복잡한가”를 나타내는 절대적 단위이다.
“이 트랜잭션은 50,000 Gas를 소비한다”
Gas는 코드 로직에 의해 결정되며, 네트워크 상황과 무관하게 일정하다.
같은 ERC-20 전송은 언제나 약 65,000 Gas를 소비한다.
GasPrice: Gas 1단위당 가격 (Legacy, Type 0)
GasPrice는 Gas 1단위를 실행하기 위해 지불할 ETH의 양이다. 단위는 gwei (1 gwei = 10^-9 ETH)이다.
GasPrice = 30 gwei 의미: “나는 1 Gas당 30 gwei를 지불하겠다”
GasPrice는 사용자가 자유롭게 설정할 수 있다.
높은 GasPrice를 설정하면 Validator(채굴자)가 우선적으로 처리하여 트랜잭션이 빠르게 포함된다.
낮은 GasPrice를 설정하면 트랜잭션이 오래 대기하거나 아예 처리되지 않을 수 있다.
GasLimit: 최대 소비 허용량
GasLimit은 “이 트랜잭션이 최대 얼마나 많은 Gas를 소비할 수 있는가”를 제한하는 안전장치이다.
GasLimit = 100,000 Gas 의미: “이 트랜잭션은 최대 100,000 Gas까지만 사용할 수 있다”
GasLimit의 세 가지 시나리오
1. 실제 사용량 < GasLimit (정상)
GasLimit = 100,000 Gas
실제 소비 = 65,000 Gas
결과: 트랜잭션 성공, 남은 35,000 Gas는 환불됨
2. 실제 사용량 > GasLimit (실패)
GasLimit = 50,000 Gas
실제 필요량 = 65,000 Gas
결과: 50,000 Gas 시점에서 트랜잭션 중단 (Out of Gas)
트랜잭션 실패 (revert)
하지만 소비된 50,000 Gas는 환불되지 않음!
Out of Gas로 실패한 트랜잭션도 Validator는 연산을 수행했으므로 Gas는 전액 소비된다.
사용자는 돈을 지불했지만 아무 일도 일어나지 않는다.
3. GasLimit이 너무 높음 (비효율)
GasLimit = 1,000,000 Gas (과도하게 높음)
실제 소비 = 65,000 Gas
결과: 트랜잭션 성공, 하지만 불필요하게 높은 GasLimit 설정
GasLimit을 지나치게 높게 설정해도 실제 소비량만 지불하므로 직접적인 손해는 없다.
하지만 일부 지갑/RPC는 GasLimit을 기반으로 트랜잭션 수용 여부를 판단하므로, 비정상적으로 높은 값은 거부될 수 있다.
EIP-1559
2021년 8월 5일, 이더리움 London Hard Fork를 통해 EIP-1559가 활성화되었다.
이는 이더리움 역사상 가장 중요한 경제적 변화 중 하나이다.
1. baseFee: 프로토콜이 결정하는 최소 가격
baseFee는 프로토콜이 자동으로 계산하는 블록별 최소 Gas 가격이다. 사용자가 추측할 필요가 없다.
baseFee는 블록마다 자동으로 조정된다.
2. maxPriorityFeePerGas (tip): Validator에게 주는 팁
사용자가 Validator에게 직접 지불하는 팁이다. baseFee는 소각되므로, Validator의 실제 수익은 이 팁뿐이다.
급한 트랜잭션은 높은 팁을 설정하여 우선 처리받을 수 있다.
3. maxFeePerGas: 지불 의향 최대 가격
사용자가 Gas 1단위당 지불할 의향이 있는 최대 가격이다.
만약 baseFee가 maxFeePerGas보다 높으면 트랜잭션은 포함되지 않는다.
실제 지불 가격: effectiveGasPrice = baseFee + min(maxPriorityFeePerGas, maxFeePerGas - baseFee)
Validator 는 이 effectiveGasPrice 가 높은 트랜잭션을 우선으로 선택한다.
EIP-1559 이후, baseFee 는 소각되고 priorityFee(tip) 만 Validator 의 수익이 된다.