什么是随机数?以太坊交易的管理技巧

  • QuickNode
  • 发布于 2025-01-23 19:48
  • 阅读 18

本文详细介绍了以太坊交易中的nonce概念,并提供了使用Ethers.js管理nonce的具体方法,适合所有想要深入理解以太坊交易机制的开发者。文章结构清晰,涵盖了基础知识、代码示例和实际操作步骤,帮助读者掌握此重要概念。

概述

每个在以太坊上的交易,无论是由外部拥有账户(EOA)发起(例如,你的 MetaMask 钱包)还是由智能合约地址发起,都包含一个 nonce。如果不正确管理这个值,交易可能会失败,因此你可能会遇到类似于 错误:nonce 太低 的问题(完整错误代码列表请参见 这里)。

在本指南中,我们将教你有关以太坊上 nonce 的所有知识,以及如何使用 Ethers.js(JavaScript)以编程方式管理此值。

让我们开始吧!

你将做什么

  • 高级回顾以太坊交易(适用于其他基于 EVM 的链)
  • 了解以太坊交易中 nonce 的基础知识
  • 掌握如何使用 Ethers.js 正确管理你以太坊地址的 nonce

你将需要

  • 安装 Node.js
  • 一个以太坊地址(例如,MetaMask、Coinbase Wallet 等)并具有访问你的私钥的权限
  • 一个 QuickNode 帐户(在此免费注册
  • 在 Sepolia 测试网的 ETH(在 这里获取 ETH
依赖项 版本
node.js 18.13.0
ethers.js 6.9.2

以太坊上的交易

在深入了解以太坊的 Nonces 之前,让我们快速回顾一下交易及其组成部分。

在以太坊上,无论是由 EOA 还是智能合约地址生成的交易,都包含一组必填字段,例如:

  • from: 发送方地址
  • to: 接收方地址
  • gasLimit: 交易可以消耗的最大 gas 量
  • maxPriorityFeePerGas: 这表示为每个消耗的 gas 单位提供的最高 gas 费用作为对验证者的小费。
  • maxFeePerGas: 这是为交易准备支付的每个 gas 单位费用的上限,包括 baseFeePerGas 和 maxPriorityFeePerGas。
  • chainId: 唯一标识你所交互的区块链的标识符
  • nonce: 你将在下一个部分学习到
  • value: 随交易发送的 ETH 数量
  • signature (v,r,s): 这是指交易的签名值

请注意,一些 Web3 SDK 将自动填充其中一些值,使开发人员更容易使用。

每当你在以太坊(或其他基于 EVM 的链)上生成交易有效载荷时,你的交易签名都是唯一的,因为它由上述字段组成。这一点很重要,原因有很多,我们将在下一部分涵盖。

如果你想了解如何在以太坊上生成交易,请查看以下指南:如何使用 Python 通过 EIP-1559 和遗留方法发送交易如何使用 Ethers.js 发送交易

什么是 Nonce?

Nonce 是包含在交易有效载荷中的一个数字,用于跟踪你的地址发送的交易数量。这个值确保从你的钱包发送的交易按顺序执行,并且不能被重放。例如,如果一个以太坊地址同时发送两个交易,一个交易的 nonce 为 1,另一个为 2,那么 nonce 值为 1 的交易需要在第二个交易之前被挖掘。这个 nonce 值还防止重放交易。例如,如果你发送了一个有效的交易并且它被挖掘,你不能向网络发送一个具有相同 nonce 值的交易。这一保护措施防止有效交易被重复使用,以试图从地址中提取资金。任何尝试重新发送具有已使用 nonce 的交易的行为都会被节点拒绝。

同样重要的是,如果你的交易已发送但未执行,你仍然可以通过提交具有相同 nonce 和更高 gas 费用的交易来替代(例如,覆盖)交易。取消交易同样适用,你可以发送具有相同 nonce 以及空有效载荷和值的交易。

此外,请注意,如果一个地址同时发送多个交易,并不是所有交易都处于 Mempool 的 pending 状态。只有当前 nonce 的交易会处于 pending 状态,而其他交易将处于 queued 状态(你可以在这篇指南中了解更多关于以太坊 mempool 的信息:待处理和排队交易解释)。

你可以通过在区块浏览器(如 Etherscan)上查看交易的详细信息来查看确认交易的 nonce。在交易下,展开“更多细节”部分,你将看到 nonce 值:

Etherscan more details pane

现在我们知道了有关 nonce 的更多信息以及它们如何影响以太坊交易,让我们向你展示如何正确管理它们。然而,在此之前,让我们首先设置与以太坊区块链的通信,并确保我们有足够的测试资金来模拟交易。

项目先决条件:创建 QuickNode 节点端点

要与以太坊进行通信,你需要访问一个节点。你可以使用公共节点,或自己部署和管理基础设施;但是,如果你希望获得 8 倍的响应速度,可以将繁重的工作交给我们。可以 在此注册免费账户

为了演示和测试本指南中的 nonce 管理,我们将在测试网(如以太坊 Sepolia)上进行交易。

登录 QuickNode 后,单击 创建端点 按钮,然后选择 以太坊 链和 Sepolia 网络。

创建端点后,复制 HTTP Provider URL 链接并保持备份,因为你将在后续部分中需要它。

Sepolia QuickNode Endpoint

项目先决条件:为你的钱包充值

要在以太坊 Sepolia 上进行交易,我们需要一些测试以太币以发送价值和支付 gas 费用。如果你需要一些,多链 QuickNode 水龙头 使获取测试 ETH 变得简单!

导航到 多链 QuickNode 水龙头,并连接你的钱包(例如,MetaMask、Coinbase Wallet)或粘贴你的钱包地址以获取测试 ETH。请注意,要使用 EVM 水龙头,你在以太坊主网需要满足 0.001 ETH 的余额要求。你还可以通过推特或使用你的 QuickNode 账户登录以获得奖金!

Multi-Chain QuickNode Faucet

如何在以太坊交易中管理 Nonce

在编码演示中,我们将展示如何同时发送五个交易,并在每个交易中递增 nonce。

打开你的终端窗口,运行以下命令创建 npm 项目及所需的文件和依赖:

mkdir ethereum-nonce-manager && cd ethereum-nonce-manager && npm init -y && echo > index.js && echo > .env && npm i ethers dotenv

打开 .env 文件,输入以下变量名称及其各自的值。HTTP_PROVIDER_URL 指的是你的 QuickNode 端点 URL,PRIVATE_KEY 指的是你钱包的私钥(用于签署交易)。

HTTP_PROVIDER_URL=
PRIVATE_KEY=

保存文件后,打开 index.js 文件并包含以下代码:

require("dotenv").config();
const ethers = require('ethers');

(async () => {
    const provider = new ethers.JsonRpcProvider(process.env.HTTP_PROVIDER_URL);
    const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

    // 获取第一个交易的当前 nonce
    let nonce = await provider.getTransactionCount(signer.address);

    // 准备一个数组以保存每个交易的 Promise
    const transactionPromises = [];

    for (let i = 0; i < 5; i++) {
        const payload = {
            from: signer.address,
            to: 'RECEIVER_ADDRESS',
            value: ethers.parseUnits('0.001', 'ether'),
            nonce: nonce + i, // 为每个交易递增 nonce
        };

        console.log("交易有效载荷生成。发送 nonce 为:", nonce + i, "的交易");

        transactionPromises.push(signer.sendTransaction(payload));
    }

    // 等待所有交易被发送
    const transactions = await Promise.all(transactionPromises);

    // 等待所有交易被挖掘
    for (const tx of transactions) {
        const receipt = await tx.wait();
        console.log("交易已挖掘: ", tx.hash);
    }
})();

在执行代码之前,让我们填写占位符值 - RECEIVER_ADDRESS。然后,通过运行命令执行交易:

node index.js

你将看到类似下方的输出:

Terminal Transaction Output

如你所见,每个交易都有一个唯一的 nonce 值,跟踪你的地址发送的交易数量。如果你只需要单个交易的代码,此处是单独的代码片段。你只需替换相同的占位符值即可。

require("dotenv").config();
const ethers = require('ethers');

(async () => {
    const provider = new ethers.JsonRpcProvider(process.env.HTTP_PROVIDER_URL);
    const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
    const nonce = await provider.getTransactionCount(signer.address)
    const payload = {
        from: signer.address,
        to: 'RECEIVER_ADDRESS',
        value: ethers.parseUnits('0.001', 'ether'),
        nonce: nonce,
    }
    console.log("交易有效载荷生成。发送 nonce 为:", nonce, "的交易")
    const tx = await signer.sendTransaction({payload});
    const receipt = await tx.wait()
    console.log("交易已挖掘: ", tx.hash)
})();

干得好!你已完成本指南的内容!

最后的想法

就是这样!你现在知道什么是 nonce,以及如何在以太坊交易中管理它!如果你有任何问题或需要进一步的帮助,欢迎加入我们的 Discord 服务器或使用下面的表单提供反馈。通过关注我们的 Twitter (@QuickNode) 和 Telegram公告频道,保持与最新动态同步。

我们❤️反馈!

让我们知道 如果你有任何反馈或对新主题的请求。我们很乐意听到你的意见。

  • 原文链接: quicknode.com/guides/eth...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。