以太坊优先费用计算器

在Etherscan交易页面显示实际的Priority Fee (小费) 计算结果,支持EIP-1559交易

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Etherscan Priority Fee Calculator | 以太坊优先费用计算器
// @name:zh-CN   以太坊优先费用计算器
// @name:en      Etherscan Priority Fee Calculator
// @namespace    https://github.com/yuouiu/etherscan-priority-fee-calculator
// @version      1.0.0
// @description  在Etherscan交易页面显示实际的Priority Fee (小费) 计算结果,支持EIP-1559交易
// @description:zh-CN  在Etherscan交易页面显示实际的Priority Fee (小费) 计算结果,支持EIP-1559交易
// @description:en   Display actual Priority Fee calculation results on Etherscan transaction pages, supporting EIP-1559 transactions
// @author       yuouiu
// @match        https://etherscan.io/tx/*
// @match        https://*.etherscan.io/tx/*
// @license      MIT
// @grant        none
// @supportURL   https://github.com/yuouiu/etherscan-priority-fee-calculator
// @homepage     https://github.com/yuouiu/etherscan-priority-fee-calculator
// @icon         https://www.ethereum.org/favicon.ico
// ==/UserScript==

(function() {
    'use strict';

    const ENDPOINT = "https://eth.blockrazor.xyz";

    // 辅助函数:将16进制转换为整数
    function hexToInt(hexStr) {
        return hexStr && hexStr.startsWith('0x') ? parseInt(hexStr, 16) : 0;
    }

    // 辅助函数:将Wei转换为Gwei
    function weiToGwei(weiStr) {
        const wei = hexToInt(weiStr);
        return wei / 1e9;
    }

    // 获取交易数据
    async function getTransactionData(txHash) {
        const payload = {
            "jsonrpc": "2.0",
            "method": "eth_getTransactionByHash",
            "params": [txHash],
            "id": 1
        };
        const response = await fetch(ENDPOINT, {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(payload)
        });
        return await response.json();
    }

    // 获取区块数据
    async function getBlockData(blockNumber) {
        const payload = {
            "jsonrpc": "2.0",
            "method": "eth_getBlockByNumber",
            "params": [blockNumber, false],
            "id": 1
        };
        const response = await fetch(ENDPOINT, {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(payload)
        });
        return await response.json();
    }

    // 获取区块收据数据
    async function getBlockReceipts(txHash) {
        const payload = {
            "jsonrpc": "2.0",
            "method": "eth_getTransactionReceipt",
            "params": [txHash],
            "id": 1
        };
        const response = await fetch(ENDPOINT, {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(payload)
        });
        return await response.json();
    }

    // 计算Priority Fee
    function calculatePriorityFee(maxPriorityFeePerGas, maxFeePerGas, baseFeePerGas, gasUsed) {
        const basePriorityFee = Math.max(0, Math.min(
            weiToGwei(maxPriorityFeePerGas),
            weiToGwei(maxFeePerGas) - weiToGwei(baseFeePerGas)
        ));
        return basePriorityFee * hexToInt(gasUsed);
    }

    // 创建显示元素
    function createPriorityFeeDisplay() {
        const container = document.createElement('div');
        container.style.padding = '10px';
        container.style.margin = '10px 0';
        container.style.backgroundColor = '#f8f9fa';
        container.style.border = '1px solid #dee2e6';
        container.style.borderRadius = '4px';
        container.id = 'priorityFeeContainer';
        return container;
    }

    // 主函数
    async function main() {
        try {
            // 从URL中获取交易哈希
            const txHash = window.location.pathname.split('/').pop();
            if (!txHash) return;

            // 获取交易数据
            const txData = await getTransactionData(txHash);
            if (!txData.result) return;

            // 获取区块数据
            const blockData = await getBlockData(txData.result.blockNumber);
            if (!blockData.result) return;

            // 获取交易收据数据
            const receiptData = await getBlockReceipts(txHash);
            if (!receiptData.result) return;

            // 计算Priority Fee
            const priorityFee = calculatePriorityFee(
                txData.result.maxPriorityFeePerGas,
                txData.result.maxFeePerGas,
                blockData.result.baseFeePerGas,
                receiptData.result.gasUsed
            );

            // 创建显示元素
            const container = createPriorityFeeDisplay();
            const priorityFeeETH = priorityFee / 1e9;
            container.innerHTML = `
                <div>Priority Fee: ${priorityFee.toFixed(9)} Gwei (${priorityFeeETH.toFixed(18)} ETH)</div>
            `;

            // 插入到页面中
            const targetElement = document.querySelector('h1').parentElement;
            if (targetElement) {
                targetElement.after(container);
            }

        } catch (error) {
            console.error('计算Priority Fee时发生错误:', error);
        }
    }

    // 页面加载完成后执行
    window.addEventListener('load', main);
})();