Ethereum(ETH) Block Explorer - Tokenview (2024)

Before EIP-1559, the gas fee on ETH used a simple auction model, and the transactions of the highest bidder were verified first. Such a calculation model will cause gas fees to fluctuate wildly due to human factors (bidding). EIP-1559 is designed to solve the problem of unpredictable and volatile gas fees.

Many apps like to give users the option to set their own gas bids, including “slow,” “average,” and “fast” options. In this article, we’ll look at how to build these options using EIP-1559 API.

1. The calculation formula of Gas Fee

units of gas used * (base fee + priority fee)

  • units of gas used The number of gas units spent on the transaction. A standard simple ETH transfer transaction requires 21,000 units of gas.
  • base fee Basic gas fee, unit is gwei (1gwei = 0.000000001 ETH)
  • priority fee The priority fee, or tip to miners, is in the same unit as the base fee, which is gwei.
  • 2. base fee

    First, the base fee is based on the base fee of the previous block. The calculation is automatically completed by the eth node, which is essentially different from the previous bidding mode. Roughly speaking, if the transaction volume of the previous block was larger, the base fee of the current block will increase, and vice versa. Such dynamic adjustments. In other words, this basic fee can be accurately calculated.

    EIP-1559 source code

    The above code is based on golang, we convert it into a simple python code:

    Copy

    from web3 import Web3eth_json_rpc_endpoint = "https://services.tokenview.io/vipapi/nodeservice/eth?apikey=xxx"ElasticityMultiplier = 2 # EIP-1559 The block size has been expanded, the maximum multiple is 2BaseFeeChangeDenominator = 8 # The amount the base fee can change between blocksdef calc_base_fee_of_next_block(parent_block): parent_gas_target = parent_block.gasLimit // ElasticityMultiplier print('parent_gas_target',parent_gas_target) print('parent_block.gasUsed',parent_block.gasUsed) print('parent_block.baseFeePerGas',parent_block.baseFeePerGas) if parent_block.gasUsed == parent_gas_target: # parent block's gasUsed is the same as the target, baseFee remains unchanged return parent_block.baseFeePerGas if parent_block.gasUsed > parent_gas_target: # parent block uses gas greater than the target value, baseFee increase gas_used_delta = parent_block.gasUsed - parent_gas_target x = parent_block.baseFeePerGas * gas_used_delta y = x // parent_gas_target base_fee_delta = max( y // BaseFeeChangeDenominator, 1 ) return parent_block.baseFeePerGas + base_fee_delta else: # the gas used by the parent block is less than the target value, baseFee reduce gas_used_delta = parent_gas_target - parent_block.gasUsed x = parent_block.baseFeePerGas * gas_used_delta y = x // parent_gas_target base_fee_delta = y // BaseFeeChangeDenominator return max( parent_block.baseFeePerGas - base_fee_delta, 0 ) def main(): ethClient = Web3(Web3.HTTPProvider(eth_json_rpc_endpoint)) block_number = ethClient.eth.block_number block = ethClient.eth.get_block(block_number) base_fee_of_next_block = calc_base_fee_of_next_block(block) print(f"Base fee for block {block_number + 1} will be {base_fee_of_next_block}")

    3. priority fee

    Unlike base fees, priority fees are artificially set values. For transactions that need to be executed first in the same block, a higher tip is required. To predict priority fees, you have to scan blocks over time to see what fees others are using.

    We will use this API:eth_feeHistory

    Copy

    from web3 import Web3eth_json_rpc_endpoint = "https://services.tokenview.io/vipapi/nodeservice/eth?apikey=xxx"ethClient = Web3(Web3.HTTPProvider(eth_json_rpc_endpoint))print(ethClient.eth.fee_history(4,"pending", [25, 50, 75]))

    The above call means, “Give me the fee history information starting from the pending block and looking backward 4 blocks. For each block also give me the 25th, 50th, and 75th percentiles of priority fees for transactions in the block”. The raw result looks like this:

    Copy

    { "oldestBlock": 17913327, "reward": [ [39519672,100000000,2000000000], [100000000,1000000000,3000000000], [100000000,365064718,1000000000], 100000000,570000000,3000000000] ], "baseFeePerGas": [ 21121728416, 21666906452, 20742307151, 19782866894, 17762883032 ], "gasUsedRatio": [ 0.6032449666666667, 0.3293066333333333, 0.31497906666666664, 0.09156903333333333 ]}

    To make our calculations easier, let’s write a formatting method that groups the above results into chunks:

    Copy

    def format_fee_history(result, include_pending): block_num = result['oldestBlock'] index = 0 blocks = [] historical_blocks = len(result['reward']) while block_num < result['oldestBlock'] + historical_blocks: blocks.append({ 'number': block_num, 'baseFeePerGas': float(result['baseFeePerGas'][index]), 'gasUsedRatio': float(result['gasUsedRatio'][index]), 'priorityFeePerGas': [float(x) for x in result['reward'][index]], }) block_num += 1 index += 1 if include_pending: blocks.append({ 'number': 'pending', 'baseFeePerGas': float(result['baseFeePerGas'][historical_blocks]), 'gasUsedRatio': float('nan'), 'priorityFeePerGas': [], }) return blocks

    Next we can get the data in this format:

    Copy

    blocks = format_fee_history(ethClient.eth.fee_history(4,"latest", [25, 50, 75]),False)print(blocks)->>[ { number: 17913335, baseFeePerGas: 315777006840, gasUsedRatio: 0.9922326809477219, priorityFeePerGas: [ 34222993160, 34222993160, 63222993160 ] }, { number: 17913336, baseFeePerGas: 354635947504, gasUsedRatio: 0.22772779167798343, priorityFeePerGas: [ 20000000000, 38044555767, 38364052496 ] }, { number: 17913337, baseFeePerGas: 330496570085, gasUsedRatio: 0.8876034775653597, priorityFeePerGas: [ 9503429915, 19503429915, 36503429915 ] }, { number: 17913338, baseFeePerGas: 362521975057, gasUsedRatio: 0.9909446241177369, priorityFeePerGas: [ 18478024943, 37478024943, 81478024943 ] }]

    Readability is greatly improved! Among them, baseFeePerGas and gasUsedRatio are used to calculate the base fee. We only focus on priorityFeePerGas now.

    Continuing with our requirements, to estimate the priority fee we need to determine two values:

    i.How much historical data should be used to estimate

    ii.How much priority do you want your transactions to have?

    For i , we set the value to 4 blocks, a reasonable length of time of about a minute.

    For ii, we set expectations as 25% 50% 75% corresponding to low, medium and high tips.

    Copy

    blocks = format_fee_history(ethClient.eth.fee_history(4,"latest", [25, 50, 75]),False)low_percential_priority_fees = [b['priorityFeePerGas'][0] for b in blocks]mid_percential_priority_fees = [b['priorityFeePerGas'][1] for b in blocks]high_percential_priority_fees = [b['priorityFeePerGas'][2] for b in blocks]low_average = sum(low_percential_priority_fees) / len(low_percential_priority_fees) mid_average = sum(mid_percential_priority_fees) / len(mid_percential_priority_fees) high_average = sum(high_percential_priority_fees) / len(high_percential_priority_fees) print(low_average,' | ',mid_average,' | ',high_average)

    The algorithm used by Tokenview is to simply average the priorityFeePerGas of the past 4 historical blocks. Of course, if you have a better estimation method, such as increasing the number of historical blocks to 20 blocks, or only considering the cheapest successful transaction. You can build your own gas cost estimator

    Thank you for reading from start to finish 🎉🎉🎉

    Ethereum(ETH) Block Explorer - Tokenview (2024)
    Top Articles
    Latest Posts
    Article information

    Author: Arielle Torp

    Last Updated:

    Views: 6457

    Rating: 4 / 5 (61 voted)

    Reviews: 84% of readers found this page helpful

    Author information

    Name: Arielle Torp

    Birthday: 1997-09-20

    Address: 87313 Erdman Vista, North Dustinborough, WA 37563

    Phone: +97216742823598

    Job: Central Technology Officer

    Hobby: Taekwondo, Macrame, Foreign language learning, Kite flying, Cooking, Skiing, Computer programming

    Introduction: My name is Arielle Torp, I am a comfortable, kind, zealous, lovely, jolly, colorful, adventurous person who loves writing and wants to share my knowledge and understanding with you.