EIP-1559는 Ethereum의 가스 요금 시스템을 구조적으로 바꾼 중요한 제안으로,
2021년 런던 하드포크에서 도입되어 현재 Ethereum 메인넷에서 사용되고 있습니다.
⸻
🚀 1. EIP-1559 등장 배경
🔥 기존 문제점 (Pre-EIP-1559)
• 경매 기반 수수료: 사용자가 높은 수수료를 제안해야 트랜잭션이 채택됨 (1st-price auction)
• 수수료 예측 어려움: 네트워크 혼잡할 때 수수료가 급등하거나 과다 지불
• UX 악화: 사용자 입장에서 적절한 가스비 계산이 어려움
⸻
🧠 2. EIP-1559의 핵심 아이디어
EIP-1559는 다음과 같은 방식으로 작동합니다:
| 구성 요소 | 설명 |
|---|---|
| baseFee | 네트워크 혼잡도에 따라 자동 조정되는 기본 수수료 |
| tip / priorityFee | 채굴자(→ 검증자)에게 직접 주는 우선 수수료 |
| maxFeePerGas | 사용자가 설정하는 지불 가능한 최대 가스비 |
| maxPriorityFeePerGas | 검증자에게 주는 팁 (우선순위 수수료) |
⸻
⚙️ 3. 새로운 가스 수수료 구조
✅ 트랜잭션 수수료 공식:
effectiveGasPrice = max(
baseFee + priorityFee,
maxFeePerGas
)
totalFee = effectiveGasPrice * gasUsed하지만 실제 사용자 지불액은 다음과 같습니다:
ActualFeePaid = min(maxFeePerGas, baseFee + priorityFee) * gasUsed
MinerReward = priorityFee * gasUsed
Burned = baseFee * gasUsed⸻
📊 각 요소 설명
| 요소 | 설명 |
|---|---|
| baseFee | 자동 조정되는 네트워크 수수료. 블록마다 변동 |
| priorityFee | 트랜잭션이 빨리 처리되도록 하는 팁 |
| maxFeePerGas | 사용자가 감당 가능한 최대 단가 (보안 벽) |
| gasLimit | 트랜잭션이 사용할 수 있는 최대 가스 |
⸻
🔥 4. baseFee 조정 방식
• 기본값: baseFeePerGas는 이전 블록의 가스 사용량에 따라 조정
• 최대 증감 폭: 블록당 ±12.5%
📈 계산 공식:
if gasUsed > targetGas:
baseFee += baseFee * (gasUsed - targetGas) / targetGas / 8
else:
baseFee -= baseFee * (targetGas - gasUsed) / targetGas / 8• targetGas: 블록의 절반 크기 (현재 블록 최대 가스 = 30M, 타겟 = 15M)
• 혼잡 → baseFee 상승
• 여유 → baseFee 하락⸻
🔥 5. baseFee는 Burn 됨 (🔥 공급 감소)
• 모든 트랜잭션의 baseFee * gasUsed는 소각(burn) 됩니다.
• Ethereum의 인플레이션을 억제하며, 디플레이션적 특성 강화
📌 이 기능이 Ethereum의 “Sound Money” 내러티브 핵심입니다.
⸻
🧪 6. 실전 예제
💼 예시
{
"gasLimit": 21000,
"maxFeePerGas": 50 gwei,
"maxPriorityFeePerGas": 2 gwei,
"baseFee": 30 gwei
}🧾 계산:
• effectiveGasPrice = baseFee + priorityFee = 30 + 2 = 32 gwei
• actualFee = 32 gwei * 21000 = 672,000 gwei = 0.000672 ETH
• burned = 30 gwei * 21000 = 630,000 gwei = 0.00063 ETH
• miner reward = 2 gwei * 21000 = 42,000 gwei = 0.000042 ETH
⸻
✅ 7. 장점 vs 단점
✅ 장점
|항목| 설명|
|수수료 예측 가능성 향상| baseFee 자동 조정|
|UX 향상| 평균적으로 더 간단한 fee 설정|
|ETH 소각| 디플레이션 기여|
|트랜잭션 낙찰 최적화| 과도한 경쟁 최소화|
⸻
❌ 단점
| 항목 | 설명 |
|---|---|
| 구조 복잡 | maxFee, priorityFee 설정이 어려움 |
| UI 설계 어려움 | wallet에서 가스 추천 로직이 복잡해짐 |
| 수수료가 높아지는 경우 있음 | 블록 포화 시 baseFee 급등 가능 |
⸻
🔧 8. 트랜잭션에 지정하는 값 요약
| 필드 | 필수 | 설명 |
|---|---|---|
| maxFeePerGas | ✅ | 지불 가능한 최대 가스비 |
| maxPriorityFeePerGas | ✅ | 검증자에게 줄 팁 |
| gasLimit | ✅ | 예상 가스량 |
| nonce | ✅ | 트랜잭션 순서 관리 |
| value | ✅ | 전송 금액 |
⸻
🎯 요약
| 항목 | 설명 |
|---|---|
| 수수료 구조 | baseFee + priorityFee |
| 설정 방식 | maxFee, maxPriorityFee 지정 |
| 계산 공식 | 실제 지불 = min(maxFee, baseFee + tip) × gasUsed |
| baseFee | 자동 조정, 블록마다 변동 |
| 소각 | baseFee는 영구 소각됨 (ETH 디플레이션 효과) |
⸻
✅ 기준 환경
• Ethereum 메인넷 or 테스트넷 (EIP-1559 적용)
• Node: web3@1.7.x, ethers@6.x
⸻
🔷 2. Ethers.js (v6 기준)
✅ 예제: 수수료 수동 설정
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_KEY");
const wallet = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);
const tx = await wallet.sendTransaction({
to: "0xReceiverAddress",
value: ethers.parseEther("0.01"),
maxPriorityFeePerGas: ethers.parseUnits("2", "gwei"),
maxFeePerGas: ethers.parseUnits("50", "gwei"),
gasLimit: 21000
});
console.log("Tx hash:", tx.hash);⸻
✅ 예제: 수수료 자동 추정 (EIP-1559 적용)
const fee = await provider.getFeeData();
console.log("baseFee:", fee.gasPrice); // = baseFee + tip
console.log("priorityFee:", fee.maxPriorityFeePerGas);
console.log("maxFee:", fee.maxFeePerGas);
const tx = await wallet.sendTransaction({
to: "0xReceiverAddress",
value: ethers.parseEther("0.01"),
gasLimit: 21000,
maxFeePerGas: fee.maxFeePerGas,
maxPriorityFeePerGas: fee.maxPriorityFeePerGas
});⸻
🔶 3. Web3.js (v1.7 기준)
✅ 예제: 수수료 수동 설정
const Web3 = require("web3");
const web3 = new Web3("https://mainnet.infura.io/v3/YOUR_KEY");
const account = web3.eth.accounts.privateKeyToAccount("0xYOUR_PRIVATE_KEY");
web3.eth.accounts.wallet.add(account);
const tx = {
from: account.address,
to: "0xReceiverAddress",
value: web3.utils.toWei("0.01", "ether"),
gas: 21000,
maxFeePerGas: web3.utils.toWei("50", "gwei"),
maxPriorityFeePerGas: web3.utils.toWei("2", "gwei"),
type: "0x2" // EIP-1559 트랜잭션 유형
};
const receipt = await web3.eth.sendTransaction(tx);
console.log("Tx hash:", receipt.transactionHash);⸻
✅ 예제: 수수료 자동 추정
const baseFee = await web3.eth.getGasPrice(); // 최신 블록의 baseFee
const priorityFee = web3.utils.toWei("2", "gwei");
const maxFee = (BigInt(baseFee) + BigInt(priorityFee)).toString();
const tx = {
from: account.address,
to: "0xReceiverAddress",
value: web3.utils.toWei("0.01", "ether"),
gas: 21000,
maxFeePerGas: maxFee,
maxPriorityFeePerGas: priorityFee,
type: "0x2"
};
const receipt = await web3.eth.sendTransaction(tx);⸻
⚠️ 주의 사항
| 항목 | 설명 |
|---|---|
| gasLimit | 명시하지 않으면 자동 추정 (estimateGas) |
| type | EIP-1559 트랜잭션은 type: 2 (0x2) |
| Web3.js | EIP-1559 지원은 v1.5.0 이후부터 가능 |
⸻
✅ 요약 정리
| 라이브러리 | 자동 수수료 | 수동 설정 | 주의사항 |
|---|---|---|---|
| Ethers.js | getFeeData() | maxFeePerGas, maxPriorityFeePerGas | ethers.parseUnits() 사용 |
| Web3.js | getGasPrice() + 수동 계산 | 수동으로 type: 2 지정 | 단위 변환 web3.utils.toWei 필요 |
'이더리움' 카테고리의 다른 글
| 스마트 컨트랙트 개발도구: web3.js vs. ethers.js (0) | 2025.03.25 |
|---|---|
| 스마트 컨트랙트 개발도구: JavaScript vs. TypeScript (0) | 2025.03.25 |
| ERC-721 의 transferFrom vs. safeTransferFrom (0) | 2025.03.25 |
| UUPS vs Transparent Proxy (0) | 2025.03.25 |
| 수정 가능한 스마트 컨트랙트 코드 예시 (0) | 2025.03.25 |