1

构建以太坊gas跟踪器

 2 years ago
source link: https://learnblockchain.cn/article/3391
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

259787ed0b905b5e83acba982f72b5dd.jpg

介绍

2021年8月的伦敦硬分叉带来了以太坊网络有史以来最大的一次升级。该分叉实现了EIP-1559;一种被吹捧为优于盲目拍卖模式的gas定价机制。它还引入了以太坊(ETH)货币政策的根本性变化,使其至少在短期内成为通货紧缩货币。

在本教程中,我们将构建一个gas跟踪器,用于跟踪EIP-1559中gas费用的两个新组成部分以及最近20个区块的其他统计数据(如区块体积)。通过这样做,我们将实现两个重要目标:

  • 更深入地理解EIP-1559的工作原理,以及它带来了哪些改进。
  • 一个功能齐全的gas跟踪应用程序,检索最新的区块数体积和gas费用,按基数和优先费用进行分类。

为了做到这一点,我们将使用Alchemy、Alchemy web3.js库、Node和React。如果这些单词对你来说听起来很陌生,不要担心,我们将详细介绍它们!

本教程假设读者对以太坊上的gas和gas价格如何工作有一个基本的了解。对EIP-1559的初步了解也有帮助,但不是必需的。

EIP-1559快速回顾

EIP-1559给以太坊的gas定价机制带来了以下变化:

  • 盲目拍卖的gas费现在被两种费用所取代:基本费和优先费(或矿工小费)。
  • 基本费用由网络自动确定。如果前一个区块是满的,它可以增加到12.5%,如果前一个区块是空的,它可以减少到12.5%。
  • 矿工的小费由用户决定,可以根据交易的紧迫性进行调优。
  • 基础费用是由网络烧的,以防止矿工人为的淹没区块。然而,矿工们可以将小费收入囊中。

除了改善gas价格,EIP-1559还提出了改进措施,以更好地装备网络,来应对突发的流量高峰。正如你可能知道的,以太坊中的交易被分组成区块。在分叉之前,无论流量怎样,一个区块只能容纳1500万的gas交易。

随着升级,区块大小上限已翻倍至3000万gas。这样做是为了更好地应对需求增长时期。然而,预计基础费用将调整为区块体积(或区块使用的gas)平均在50%或1500万gas左右。

可以通过我们制作的gas跟踪器实时看到这一切是如何工作的。我们将分两部分构建这个项目:在第一部分中,我们将编写一个节点脚本,实时跟踪交易费用的历史记录。在第二部分,我们将利用这个脚本创建一个React应用程序来构建最终的跟踪器。

第1部分:交易费用历史记录脚本

在本节中,我们将编写一个脚本(在节点中),它将允许我们获得以太坊网络上最近20个区块的gas费的历史记录。

步骤0:安装node和npm

ff2e2e1c19746e22d2a628e6c7662b87.jpg

确保在本地计算机上安装了node和npm(至少是v14或更高版本)。

步骤1:创建一个Alchemy帐户

为了获得区块最新的gas费历史记录,我们需要连接到以太坊网络进行通信。Alchemy是一个区块链开发平台,它允许我们无需启动我们自己的节点就可以实现这一点。

步骤2:创建Alchemy应用程序(和API密钥)

80ce97d9ce3efcd250a365dcc4016680.jpg

在Alchemy仪表板上创建一个应用程序。链设置为以太坊,网络设置为主网。

7e036ac5432920a7856d270361b0b556.jpg

接下来,访问你的应用程序页面,点击View Key。这将打开一个包含应用程序的HTTP和Websocket URL的弹出窗口。在本教程中,我们将使用Websocket URL。

步骤3:创建节点项目并安装依赖项

现在我们可以开始编写节点脚本了。让我们创建一个空的存储库并安装依赖项。对于这个脚本,我们将需要Alchemy web3.js库。

在你的终端(或命令提示符)上,运行以下命令:

mkdir gas-tracker-script && cd gas-tracker-script > npm init -y > npm install --save @alch/alchemy-web3 > touch main.js

这将创建一个名为gas tracker-script的存储库,其中包含我们需要的所有文件和依赖项。在您喜欢的代码编辑器中打开此回购。我们将在main.js文件中编写所有的代码。

步骤4:使用Alchemy创建一个web3客户端实例

使用Alchemy web3创建客户端实例非常简单。

在main.js文件中,添加以下代码行:

const { createAlchemyWeb3 } = require("@alch/alchemy-web3");// Using WebSockets
const web3 = createAlchemyWeb3(
    "wss://eth-mainnet.alchemyapi.io/v2/<--API KEY-->",

);

确保用应用程序的 websocket URL 替换上面的占位符。

步骤5:获取最近20个区块的历史记录

我们想要最近10个区块的 gas 费用历史记录。我们感兴趣的数据包括基本费用、优先费用范围、区块体积和区块编号。

幸运的是,Alchemy有一个非常方便的eth_feeHistory,它可以自动返回前面提到的所有数据。

我们需要指定的是我们想要数据的最新区块,要查看的区块总数,以及优先费用的百分比范围。

我们感兴趣的是最近的20个区块以及优先费用的第 25、50 和 75 个百分位感兴趣。

web3.eth.getFeeHistory(20, "latest", [25, 50, 75]).then(console.log)

运行这个脚本(使用node main.js)应该会获取你正在寻找的数据。这里是一些数据,我在请求5个区块数据后收到的结果。

980a7dea3a9e8e9a43b586e0f933a9b2.jpg

步骤6:格式化输出

我们在第5步中收到的输出是正确的,但可读性不强。费用是用十六进制表示的,数据结构使得很难找出哪个数据对应哪个区块。

让我们编写一个小函数,将原始数据转换为一个字典列表,其中每个字典将包含特定区块上的数据。该函数还将所有以wei表示的十六进制gas值转换为以Gwei表示的十进制数。

const formatOutput = (data, numBlocks) => {    let blocks = []
    for (let i = 0; i < numBlocks; i++) {
        blocks.push({
            blockNumber: Number(data.oldestBlock) + i,
            reward: data.reward[i].map(r => Math.round(Number(r) / 10 ** 9)),
            baseFeePerGas: Math.round(Number(data.baseFeePerGas[i]) / 10 ** 9),
            gasUsedRatio: data.gasUsedRatio[i],
        })
    }
    return blocks;

最后,让我们将此函数用作feeHistory

const numBlocks = 5;web3.eth.getFeeHistory(numBlocks, "latest", [25, 50, 75]).then((data) => {
    const blocks = formatOutput(data, numBlocks);
    console.log(blocks);
});

运行这个版本的脚本应该会产生如下格式的输出:

ac68a2fe1b23de7de6c049c77b3dc9f5.jpg

步骤7:订阅最新的block header

以太坊区块链大约每15秒新增一个区块。因此,理想情况下,我们希望订阅正在添加的区块的事件,并更新我们的交易历史,这样它总是显示最近20个区块的数据。

让我们在订阅事件回调中嵌套getFeeHistory功能。

let subscription = web3.eth.subscribe('newBlockHeaders');subscription.on("data", () => {
    web3.eth.getFeeHistory(numBlocks, "latest", [25, 50, 75]).then((data) => {
        const blocks = formatOutput(data, numBlocks);
        console.log(blocks);
    });
});

现在运行main.js脚本将每15秒左右输出一批最新的数据。如果你已经走了这么远,恭喜你!你现在有了一个功能齐全的gas跟踪器。

第2部分:React应用程序

f227aadbaedd09a5bed334fcc1c16a65.jpg

在上一节中,我们编写了一个脚本,每次向以太坊主网添加一个新区块时,它都会检索最近20个区块的费用历史记录。

在本节中,我们将构建一个小型React应用程序,将这些数据从终端传输到浏览器。除了费用交易历史,我们还将显示过去20个区块的平均gas费用和区块体积。

步骤1:初始化React项目并安装依赖项

执行如下命令:

npx create-react-app gas-tracker-frontend > cd gas-tracker-frontend

这将创建一个示例React项目。除了react依赖项之外,我们还需要安装上一节中的Alchemy web3库。

npm install --save @alch/alchemy-web3

步骤2:填充App.js文件

我们所有的逻辑都将驻留在App.js文件中。复制以下内容到上述文件。

import './App.css';
import { useEffect, useState } from 'react';
import { createAlchemyWeb3 } from '@alch/alchemy-web3';const NUM_BLOCKS = 20;function App() {  const [blockHistory, setBlockHistory] = useState(null);
  const [avgGas, setAvgGas] = useState(null);
  const [avgBlockVolume, setAvgBlockVolume] = useState(null);  const formatOutput = (data) => {    let avgGasFee = 0;
    let avgFill = 0;
    let blocks = [];    for (let i = 0; i < NUM_BLOCKS; i++) {      avgGasFee = avgGasFee + Number(data.reward[i][1]) + Number(data.baseFeePerGas[i])
      avgFill = avgFill + Math.round(data.gasUsedRatio[i] * 100);      blocks.push({
        blockNumber: Number(data.oldestBlock) + i,
        reward: data.reward[i].map(r => Math.round(Number(r) / 10 ** 9)),
        baseFeePerGas: Math.round(Number(data.baseFeePerGas[i]) / 10 ** 9),
        gasUsedRatio: Math.round(data.gasUsedRatio[i] * 100),
      })
    }    avgGasFee = avgGasFee / NUM_BLOCKS;
    avgGasFee = Math.round(avgGasFee / 10 ** 9)    avgFill = avgFill / NUM_BLOCKS;
    return [blocks, avgGasFee, avgFill];
  }  useEffect(() => {    const web3 = createAlchemyWeb3(
      "wss://eth-mainnet.alchemyapi.io/v2/<--API KEY-->",
    );    let subscription = web3.eth.subscribe('newBlockHeaders');    subscription.on('data', () => {
      web3.eth.getFeeHistory(NUM_BLOCKS, "latest", [25, 50, 75]).then((feeHistory) => {
        const [blocks, avgGasFee, avgFill] = formatOutput(feeHistory, NUM_BLOCKS);
        setBlockHistory(blocks);
        setAvgGas(avgGasFee);
        setAvgBlockVolume(avgFill);
      });
    });    return () => {
      web3.eth.clearSubscriptions();
    }
  }, [])
  return (
    <div className='main-container'>
      <h1>EIP-1559 Gas Tracker</h1>
      {!blockHistory && <p>Data is loading...</p>}
      {avgGas && avgBlockVolume && <h3>
        <span className='gas'>{avgGas} Gwei</span> | <span className='vol'>{avgBlockVolume}% Volume</span>
      </h3>}
      {blockHistory && <table>
        <thead>
          <tr>
            <th>Block Number</th>
            <th>Base Fee</th>
            <th>Reward (25%)</th>
            <th>Reward (50%)</th>
            <th>Reward (75%)</th>
            <th>Gas Used</th>
          </tr>
        </thead>
        <tbody>
          {blockHistory.map(block => {
            return (
              <tr key={block.blockNumber}>
                <td>{block.blockNumber}</td>
                <td>{block.baseFeePerGas}</td>
                <td>{block.reward[0]}</td>
                <td>{block.reward[1]}</td>
                <td>{block.reward[2]}</td>
                <td>{block.gasUsedRatio}%</td>
              </tr>
            )
          })}
        </tbody>
      </table>}
    </div>
  );
}export default App;

因为这不是一门React课程,所以我们不打算深入研究React特有的部分。但是你应该能够观察到,我们所做的只是像我们在脚本中所做的那样检索费用历史记录并以 HTML 表格的形式输出它。

我们使用的唯一附加逻辑是计算20个区块的平均gas价格和平均区块体积,这是一项微不足道的任务。

(可选)步骤3:添加一些样式

你可以在App.css文件中添加一些基本的样式,如下所示:

.main-container {
    text-align: center;
}table {
    border-collapse: collapse;
    margin: 20px auto;
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}thead {
    background: linear-gradient(267.45deg,#05d5ff -34.23%,#53f 99.39%);
    color: white;
    padding: 10px;
}th {
    font-size: 18px;
    padding: 15px;}tbody > tr {
    border-top: 1px solid #ccc; 
    border-bottom: 1px solid #ccc;
    margin: 0px;
    padding: 15px;
}td {
    padding: 6px;
}.gas {
    color: #4299E1;
}.vol {
    color: #4C51BF;

步骤4:将应用程序部署到localhost

我们都完成了。通过运行查看你的应用程序:

npm start

这是应用程序应该看起来的样子:

5c62eeca3ce55d986edf1265db78f0a6.jpg

恭喜你!你做了一个功能齐全的gas追踪应用。

分析

让我们回过头来分析一下上面的数据。以下是我们可以观察到的EIP-1559实现的直接结果。

  • 基本费用不会在每个区块之间波动很大。事实上,它最大的增减幅度是12.5%。
  • 在大多数情况下,优先费只占总费用的一小部分。
  • 区块体积倾向于波动,但平均区块体积徘徊在50%左右。

数据似乎表明,在这个模型中,gas费用的可预测性要高得多。由于每个人都要支付相同的基本费用和优先费用,在大多数情况下,优先费用只占总费用的一小部分,所以大多数交易最终不会为gas支付过高的费用。因此,这个样本数据表明,EIP-1559已经成功实现了它的目标;更可预测的gas价格,更少的gas超额支付。

结论

在本文中,我们已经讨论了很多内容。通过从头构建EIP-1559的gas跟踪器,我希望大家能够理解并欣赏它给以太坊交易带来的改进。

我还希望大家已经很好地掌握了如何使用Alchemy、它的API和web3.js库。关于它的功能和提供的产品,我们仅仅触及了表面。我强烈建议,当你开始构建下一个伟大的dapp时,你应该深入挖掘他们的文档。

Source:https://medium.com/scrappy-squirrels/building-an-ethereum-gas-tracker-e7cd6fd5b691

关于

ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

Layer 2道友 - 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”

本文首发于:https://mp.weixin.qq.com/s/aCyVGyxXwcscIy4PxMgfvw


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK