Geth - Gas

CHOYEAH·2023년 11월 30일
0

Go ethreume

목록 보기
8/11

Gas

  • Gas: 트랜잭션을 네트워크에 전송할때 소비되는 비용
  • 존재이유1: 가스가 없다면 블록체인 네트워크에 무분별한 트랜잭션을 전송하여 DDOS 공격을 당할 수 있음, 가스라는 이용료를 부과하여 네트워크를 보호할 수 있음
  • 존재이유2: 또한 네트워크를 사용하기 위한 수단으로 Ether의 필요성을 부여
  • 존재이유3: 채굴자들의 보상으로 네트워크 참여 유도
  • gas: 트랜잭션에 사용할 가스양 (리터 개념), 트랜잭션 처리에 사용되는 가스가 남으면 환불됨
  • gasPrice: 1가스당 가격 (리터당 가격 개념), gasPrice를 높게 책정하면 마이너가 우선적으로 트랜잭션을 처리, 단위는 gwei(10^-9 ETH)
  • Block의 gasLimit: 블록이 허용할 트랜잭션들의 양을 제한, 트랜잭션의 가스 리밋은 블록의 가스 리밋을 넘을 수 없음
  • Block의 gasUsed: 해당 블록에 담긴 트랜잭션들의 gasUsed 총합
  • txFee 제한(RPCTxFeeCap): 트랜잭션 전송시의 (gas*gasPrice)는 설정된 RPCTxFeeCap을 초과할 수 없음, 디폴트는 1ETH
// Defaults contains default settings for use on the Ethereum main net.
var Defaults = Config{
	SyncMode:           downloader.SnapSync,
	NetworkId:          0, // enable auto configuration of networkID == chainID
	TxLookupLimit:      2350000,
	TransactionHistory: 2350000,
	StateHistory:       params.FullImmutabilityThreshold,
	LightPeers:         100,
	DatabaseCache:      512,
	TrieCleanCache:     154,
	TrieDirtyCache:     256,
	TrieTimeout:        60 * time.Minute,
	SnapshotCache:      102,
	FilterLogCacheSize: 32,
	Miner:              miner.DefaultConfig,
	TxPool:             legacypool.DefaultConfig,
	BlobPool:           blobpool.DefaultConfig,
	RPCGasCap:          50000000,
	RPCEVMTimeout:      5 * time.Second,
	GPO:                FullNodeGPO,
	RPCTxFeeCap:        1, // 1 ether
}

/go-ethereum/eth/ethconfig/config.go

eip1559 이후 변경된 내용

baseFeePerGas:

이더리움 프로토콜에 의해 결정되는 최소 가스 프라이스(wei단위)로 트랜잭션이 블록에 포함되기 위해서 baseFeePerGas 보다 높은 가격을 지정해야한다.

geth 코드상에서는 baseFee의 변수명을 사용.

> eth.getBlock(38)
{
  baseFeePerGas: 6256137,
  difficulty: 133445,
  extraData: "0xd983010a1a846765746888676f312e31382e358664617277696e",
  gasLimit: 8302244,
  gasUsed: 21000,
  hash: "0xe70cb707ac576775a55408a1f5e61639f80ac89603b11df1acd0f09add3f9fe1",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x2da28e108530892c660dca151762ec3304b63127",
  mixHash: "0x08296c14fe7771b511dcca098242bffdbb675c75df25cfddc8d04f271bb15eb1",
  nonce: "0x6e61f0e728d36aba",
  number: 38,
  parentHash: "0xf8382ff2896a32ad08062217e1e8c8df2157acbb8e78c14fe9a66495d794d5a3",
  receiptsRoot: "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 665,
  stateRoot: "0x7de581c221fa8f5ded8d3778837be28dc7b22368be75e5d2fdf3abbdaa2fcb8d",
  timestamp: 1701308833,
  totalDifficulty: 5025744,
  transactions: ["0x4edc488026b86df0ae9f79e23b969f90e2a2f7e2b9912dce1f721efe01a94ccb"],
  transactionsRoot: "0xbac00b41a1370f63400f6cb4ce3a4e18eefa54abd3870c94d084d6eb3e59e550",
  uncles: []
}

baseFee는 CalcBaseFee()에서 계산된다.

// /go-ethereum/consensus/misc/eip1559/eip1559.go

// CalcBaseFee calculates the basefee of the header.
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
	// If the current block is the first EIP-1559 block, return the InitialBaseFee.
	if !config.IsLondon(parent.Number) {
		return new(big.Int).SetUint64(params.InitialBaseFee)
	}

	parentGasTarget := parent.GasLimit / config.ElasticityMultiplier()
	// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
	if parent.GasUsed == parentGasTarget {
		return new(big.Int).Set(parent.BaseFee)
	}

	var (
		num   = new(big.Int)
		denom = new(big.Int)
	)

	if parent.GasUsed > parentGasTarget {
		// If the parent block used more gas than its target, the baseFee should increase.
		// max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
		num.SetUint64(parent.GasUsed - parentGasTarget)
		num.Mul(num, parent.BaseFee)
		num.Div(num, denom.SetUint64(parentGasTarget))
		num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
		baseFeeDelta := math.BigMax(num, common.Big1)

		return num.Add(parent.BaseFee, baseFeeDelta)
	} else {
		// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
		// max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
		num.SetUint64(parentGasTarget - parent.GasUsed)
		num.Mul(num, parent.BaseFee)
		num.Div(num, denom.SetUint64(parentGasTarget))
		num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
		baseFee := num.Sub(parent.BaseFee, num)

		return math.BigMax(baseFee, common.Big0)
	}
}

트랜잭션에는 maxFeePerGas와 maxPriorityPerGas가 추가되었다.

maxFeePerGas (GasFeeCap)

  • 트랜잭션이 처리되기 위해 지불할 최대 가스 프라이스.
  • 실제로 지불되는 가스비는 maxFeePerGas 보다 낮을 수 있음.
  • 트랜잭션의 maxFeePerGas는 baseFee 보다는 높아야함
  • 1559 이전에는 트랜잭션에 사용된 가스 수수료가 채굴자에게 지불되었지만 1559 이후에는 baseFee만큼의 가스 수수료는 채굴자에게 지불되지 않고 소각된다.

maxPriorityFeePerGas(GasTipCap)

  • 채굴자에게 지불되는 수수료
  • 이더리움 2.0에서는 합의 클라이언트에 지정된 Fee recepient에게 지불된다.
  • 트랜잭션 생성자가 지불하는 Total Gas Fee = (baseFee + MaxPriorityPerGas) * gas
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether"), gas: 21000, maxFeePerGas: web3.toWei(1, "gwei"), maxPriorityFeePerGas: web3.toWei(1, "gwei")})
"0x8ce9ba0d314d0ec5c39e82d62d7b17fcfd3782cdb6233a35bde82666c5a3dcc3"
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether"), gas: 21000, maxFeePerGas: web3.toWei(1, "gwei"), maxPriorityFeePerGas: web3.toWei(1, "gwei")})
"0x58be26891bddb2515000da18c21822a00851ad9ec397c1682fb2f1916fed5c5f"


> eth.getTransaction("0x8ce9ba0d314d0ec5c39e82d62d7b17fcfd3782cdb6233a35bde82666c5a3dcc3")
{
  accessList: [],
  blockHash: "0x3309158bfba881b4bb93f6835684799deeda7ffc40410cb87773e0115c1d2e14",
  blockNumber: 2026,
  chainId: "0x3039",
  from: "0x2da28e108530892c660dca151762ec3304b63127",
  gas: 21000,
  gasPrice: 1000000000,
  hash: "0x8ce9ba0d314d0ec5c39e82d62d7b17fcfd3782cdb6233a35bde82666c5a3dcc3",
  input: "0x",
  maxFeePerGas: 1000000000,
  maxPriorityFeePerGas: 1000000000,
  nonce: 2,
  r: "0xbdafaa196adc77995e04e2284a966f1bbfa1b1590a8b3eb27ad46fa40baa5c2",
  s: "0x3bf915c056895a8f5b7051160481b6d76107d466ed85109f1be1296118dc6972",
  to: "0x7a37056b9fe5bf9d3ee613529e3db76ab5e46e1d",
  transactionIndex: 0,
  type: "0x2",
  v: "0x0",
  value: 1000000000000000000
}

type: "0x2"로, 다이나믹 트랜잭션 타입

> eth.getBlock(2026)
{
  baseFeePerGas: 7,
  difficulty: 330779,
  extraData: "0xd983010a1a846765746888676f312e31382e358664617277696e",
  gasLimit: 30000000,
  gasUsed: 42000,
  hash: "0x3309158bfba881b4bb93f6835684799deeda7ffc40410cb87773e0115c1d2e14",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x2da28e108530892c660dca151762ec3304b63127",
  mixHash: "0x886fbbbc2d778bc00b137f5d06da700862f42d6fb5089b50a26e057b6280a1f9",
  nonce: "0x055a47a890dda6fa",
  number: 2026,
  parentHash: "0x8431ccd3bb56fa610a5d026ba7cadc4ff198c639edb49fb5292a4158b056e0df",
  receiptsRoot: "0x75308898d571eafb5cd8cde8278bf5b3d13c5f6ec074926de3bb895b519264e1",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 786,
  stateRoot: "0xd7064b8b2c128d61332fbc962839a16e93c8f6b595d7b6bb4ab6473072ceeea8",
  timestamp: 1701314724,
  totalDifficulty: 441298049,
  transactions: ["0x8ce9ba0d314d0ec5c39e82d62d7b17fcfd3782cdb6233a35bde82666c5a3dcc3", "0x58be26891bddb2515000da18c21822a00851ad9ec397c1682fb2f1916fed5c5f"],
  transactionsRoot: "0x47326258881da5e8c994f4fe13b43f5fc500d3ae6cef7ca80725f1b2932edd20",
  uncles: []
}
profile
Move fast & break things

0개의 댓글