@flashbots/ethers-provider-bundle

中文文档
1.0.0发布于 2024/02/06ISCTypeScriptCommonJS零依赖近 30 天下载 1.3万

此寄存器包含 FlashbotsBundleProvider 乙醚.js 供应商,额外 Provider 改为 ethers.js 使高级别人员能够进入 eth_sendBundle 财务报告和审定财务报表 eth_callBundle 结束点 中继。 。 。 .

中文使用文档
文档目录15 节
  1. 示例
  2. 捆绑交易
  3. 锁定目标
  4. 天然气价格和EIP-1559
  5. 模拟和发送
  6. Flashbots 交易响应
  7. 可选的 eth sendBundle 参数
  8. 分钟时间戳/ 最大时间戳
  9. 恢复交易
  10. 付你的钱
  11. 包和用户统计
  12. 调查损失
  13. 如何运行演示( T)
  14. 发送私人交易
  15. Goerli 上的闪光机器人

乙醚提供者-发光机器人-捆绑

此寄存器包含 FlashbotsBundleProvider 乙醚.js 供应商,额外 Provider 改为 ethers.js 使高级别人员能够进入 eth_sendBundle 财务报告和审定财务报表 eth_callBundle 结束点 中继。 。 。 . mev-relay 是主机服务; 不需要运行 mev-relay 或者说 mev-geth 以这个例子为例.

Flashbots启用的中继器和矿工暴露出两个新的jsonrpc端点: eth_sendBundle 财务报告和审定财务报表 eth_callBundle。由于这些是非标准终点,ethers.js和其他库不支持这些请求(如: getTransactionCount) (中文(简体) ). 为了与这些端点互动,您需要访问另一个全天候(非Flashbots)端点进行非计算,气体估计和交易状态.

图书馆提供的一个关键特征是 有效载荷签名,要求将 Flashbot 捆绑提交 mev-relay 服务。 这个库通过 authSigner 传入建筑师. 有关中继签名的更多信息, 请查看这里

此库不是一个完全功能化的醚. js 执行,只是一个简单的提供者类,旨在与现有的 醚.js v6 安装。 。 。 .

示例

安装 ethers.js 和 Flashbots ethers 捆绑供应商 .

npm install --save ethers
npm install --save @flashbots/ethers-provider-bundle

打开一个新的 TypeScript 文件( 如果您愿意, 这也与 JavaScript 一起工作)

import { JsonRpcProvider, Wallet } from "ethers";
import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle";

// Standard json rpc provider directly from ethers.js (NOT Flashbots)
const provider = new JsonRpcProvider(ETHEREUM_RPC_URL, 1)

// `authSigner` is an Ethereum private key that does NOT store funds and is NOT your bot's primary key.
// This is an identifying key for signing payloads to establish reputation and whitelisting
// In production, this should be used across multiple bundles to build relationship. In this example, we generate a new wallet each time
const authSigner = Wallet.createRandom();

// Flashbots provider requires passing in a standard provider
const flashbotsProvider = await FlashbotsBundleProvider.create(
  provider, // a normal ethers.js provider, to perform gas estimiations and nonce lookups
  authSigner // ethers.js signer wallet, only for signing request payloads, not transactions
)

从这里,你有 flashbotsProvider 对象设置,现在可以执行其中之一 eth_callBundle (通过) simulate())或(或) eth_sendBundle (通过) sendBundle) (中文(简体) ). 其中每一项职能都以下列一系列方式发挥作用: Bundle Transactions

捆绑交易

两者 simulate 财务报告和审定财务报表 sendBundle 运行于一系列严格有序的交易。 虽然采矿者需要签名交易,但提供者库将接受预先签名交易和 TransactionRequest + Signer 交易(它将估算、非计算和在发送到 mev-relay(中文(简体) )

const wallet = new Wallet(PRIVATE_KEY)
const transaction = {
  to: CONTRACT_ADDRESS,
  data: CALL_DATA
}
const transactionBundle = [
    {
      signedTransaction: SIGNED_ORACLE_UPDATE_FROM_PENDING_POOL // serialized signed transaction hex
    },
    {
      signer: wallet, // ethers signer
      transaction: transaction // ethers populated transaction object
    }
  ]

锁定目标

最后需要的东西 sendBundle() 正在锁定目标 每个捆绑都具体提到一个块。 如果您的捆绑对多个块有效(包括所有块直到被布雷), sendBundle() 每一个区块都必须呼叫,最好是在前面的一个区块上。 这让你有机会重新评价你抓住的机会, 并重新签下一个更高的非ce,必要时.

街区应该永远是一个 未来 block, 绝不是当前 .

const targetBlockNumber = (await provider.getBlockNumber()) + 1

天然气价格和EIP-1559

EIP-1559启用前,搜索者提交交易的最常用方式是使用 gasPrice=0时,向 block.coinbase 以交易成功为条件。 所有交易都必须支付 baseFee 现在,一个街区的属性。 例如,如何确保您正在使用这个 baseFee,参见 demo.ts 在此仓库中.

const block = await provider.getBlock(blockNumber)
const maxBaseFeeInFutureBlock = FlashbotsBundleProvider.getMaxBaseFeeInFutureBlock(block.baseFeePerGas, BLOCKS_IN_THE_FUTURE)
const eip1559Transaction = {
    to: wallet.address,
    type: 2,
    maxFeePerGas: PRIORITY_FEE.add(maxBaseFeeInFutureBlock),
    maxPriorityFeePerGas: PRIORITY_FEE,
    gasLimit: 21000,
    data: '0x',
    chainId: CHAIN_ID
}

FlashbotsBundleProvider.getMaxBaseFeeInFutureBlock 计算可能的最大基准Fee BLOCKS_IN_THE_FUTURE 区块,每个区块的最大扩展。 你将不支付这个费用, 只要它被指定为 maxFeePerGas,你只支付街区的 baseFee。 。 。 .

另外,如果你拥有 baseFeePerGas, (中文(简体) ), gasUsed,以及 gasLimit 从当前区块开始,未来只针对一个区块,您可以使用 FlashbotsBundleProvider.getBaseFeeInNextBlock。该方法执行基于 EIP1559定义

模拟和发送

现在我们有了:

  1. Flashbots 供应商 flashbotsProvider
  2. 交易包 transactionBundle
  3. 块数 targetBlockNumber

我们可以运行模拟 直接提交矿工,通过 mev-relay。 。 。 .

模拟 :

  const signedTransactions = await flashbotsProvider.signBundle(transactionBundle)
  const simulation = await flashbotsProvider.simulate(signedTransactions, targetBlockNumber)
  console.log(JSON.stringify(simulation, null, 2))

发送 :

const flashbotsTransactionResponse = await flashbotsProvider.sendBundle(
  transactionBundle,
  targetBlockNumber,
  )

Flashbots 交易响应

打电话后 sendBundle,该提供者将返回与您提交的捆绑相关的辅助对象的保证.

这些函数返回在交易提交时间可用的元数据,以及以下可以等待,跟踪并模拟捆绑行为的函数.

  • bundleTransactions() - 发送到中继器的一系列交易描述,包括散列、非ce和原始交易.
  • receipts() - 返回与作为捆绑的一部分转发的交易散列相应的一系列交易收据的承诺。 将不等待块被布雷;可能返回不完整的信息
  • wait() - 返回承诺,等待达到目标区块号 或 其中一项交易由于非现金问题而变得无效(包括但不限于从您的捆绑中提取的一笔交易太早)。 返回等待解析为状态表
  • simulate() - 一旦达到适当的区块高度,就返回交易模拟的承诺。 3⁄4 ̄ ̧漯B

可选的 eth sendBundle 参数

在目标块数之外,对象可以带有可选属性:

{
  minTimestamp, // optional minimum timestamp at which this bundle is valid (inclusive)
  maxTimestamp, // optional maximum timestamp at which this bundle is valid (inclusive)
  revertingTxHashes: [tx1, tx2] // optional list of transaction hashes allowed to revert. Without specifying here, any revert invalidates the entire bundle.
}

分钟时间戳/ 最大时间戳

虽然每个捆绑的目标只有一个块,但可以根据块的时间戳来添加一个过滤器以获取有效性. 这个可以 没有 允许根据时间戳瞄准任何区块编号,或指示矿工使用何种时间戳,它只是作为二级过滤器.

如果您的捆绑在某一时间之前无效, 或者包含一个已到期的机会, 设置这些值可以让矿工在阶段的早些时候跳过捆绑处理 .

此外,今后你可以瞄准几个区块,但使用严格的最大时标,确保考虑在一定时间内将你的捆绑纳入其中,无论在那个时间范围内布设了多快的区块.

恢复交易

如果交易包包括,则不考虑列入 任意 返回或失败的交易。 虽然这通常是可取的,但有些先进的使用情况是,查询人可能希望将失败的交易带入链条。 这通常对非现金管理是可取的。 考虑:

Nonce # 1 = 失败( 无关) 令牌转让 第2号交易=DEX交易

如果搜索者想将 #2 带入链中,则必须先包含 #1,其失败与所期望的交易 #2无关. 这在高气压时期特别常见.

可选参数 revertingTxHashes 允许查询者指定可以(但不需要)返回的一系列交易.

付你的钱

除了支付装有天然气价格的捆绑外,捆绑还可以通过下列方式有条件地支付矿工的费用: block.coinbase.transfer(_minerReward) 或者说 block.coinbase.call{value: _minerReward}("");

(假定 微分奖励是一种固态) uint256 将微值直接转让给矿工)

捆绑的全部价值在结尾处相加,所以并不是每个交易都需要有气价或 block.coinbase 支付,只要至少一个支付,并支付足够支持非支付交易中使用的气体.

注意 : 如果交易尚未存在于混合体中, 燃气费将只会对您的捆绑有益 。 当将待决交易包含在捆绑中时,类似于天然气价格为 0; 捆绑中的其他交易需要支付更多的气体.

包和用户统计

Flashbots 中继器也可以返回关于您作为一个用户(仅由您的签名地址识别)和任何先前提交的捆绑的统计数据.

  • getUserStats() 返回关于过去性能的汇总度量,包括如果您的签名密钥目前符合“高优先级”队列的条件. 更多关于搜索者的名声

  • getBundleStats(bundleHash, targetBlockNumber) 返回单个捆绑提交的具体数据,包括捆绑到矿工之前各个阶段的详细时间戳。 你可以从模拟中获得捆绑的哈什:

    const simulation = await flashbotsProvider.simulate(signedTransactions, targetBlockNumber)
    console.log(simulation.bundleHash)
    

调查损失

当您的捆绑未能降落在指定的区块中时, 有很多原因可以发生这种情况 。 列出原因,请检查 Flashbots Docs:为什么我的交易没有被包括在内?. 为了帮助排除出问题,这个库提供了一种方法,可以模拟一个捆绑在多个位置上,以识别被连锁捆绑的相竞捆绑(如果有的话)并计算相关的定价.

使用说明请查看 demo-research.ts。 。 。 .

如何运行演示( T)

包括一个简单的演示,说明如何用认证签名器验证Flashbots Provider并提交一个[不起作用]捆绑。 这将不产生任何 mev,而是作为样本初始化,帮助您整合到自己的功能搜索器中.

发送私人交易

送一个 单人 交易,无需作为捆绑发送,请使用 sendPrivateTransaction 函数。 这种方法使我们能够比常规捆绑更快,更高效地处理交易. 当你使用这种方法发送交易时,我们将尝试在接下来的25个区块上(最多但不会超过目标区块号)发送给矿工.

const tx = {
    from: wallet.address,
    to: wallet.address,
    value: "0x42",
    gasPrice: 99n * BigInt(1e9), // 99 gwei
    gasLimit: 21000n,
}
const privateTx = {
    transaction: tx,
    signer: wallet,
}

const res = await flashbotsProvider.sendPrivateTransaction(privateTx)

可选的,您可以设置以下参数来微调您的提交 :

// highest block number your tx can be included in
const maxBlockNumber = (await provider.getBlockNumber()) + 10;
// timestamp for simulations
const minTimestamp = 1645753192;

const res = await flashbotsProvider.sendPrivateTransaction(
  privateTx,
  {maxBlockNumber, minTimestamp}
)

Goerli 上的闪光机器人

为了在去主网前测试Flashbots,可以使用Goerli Flashbots中继器,它与Flashbots启用的Goerli验证器配合工作. Goerli上的闪光机器人需要两个简单的改变:

  1. 确保您的通用Provider通过 FlashbotsBundle Provider 构建器与 Goerli 连接( 气体估算和非ce 请求需要对应正确的链) :
import { getDefaultProvider } from 'ethers'
const provider = getDefaultProvider('goerli')
  1. 将中继端点设置为 https://relay-goerli.flashbots.net/
const flashbotsProvider = await FlashbotsBundleProvider.create(
  provider,
  authSigner,
  'https://relay-goerli.flashbots.net/',
  'goerli')

版本与发布记录

@flashbots/ethers-provider-bundle 共发布 22 个版本,首次发布于 2020/12/11;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.0.0latest2024/02/062 年前
0.6.22023/05/193 年前
0.6.12023/01/033 年前
0.6.02022/12/173 年前
0.5.02022/07/074 年前
0.4.42022/06/304 年前

关于 @flashbots/ethers-provider-bundle 的常见问题

@flashbots/ethers-provider-bundle 是什么?

此寄存器包含 FlashbotsBundleProvider 乙醚.js 供应商,额外 Provider 改为 ethers.js 使高级别人员能够进入 eth_sendBundle 财务报告和审定财务报表 eth_callBundle 结束点 中继。 。 。 .

如何安装 @flashbots/ethers-provider-bundle?

在项目目录运行 npm install @flashbots/ethers-provider-bundle,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:ethers(6.7.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@flashbots/ethers-provider-bundle 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@flashbots/ethers-provider-bundle 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@flashbots/ethers-provider-bundle 可以商用吗?

@flashbots/ethers-provider-bundle 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@flashbots/ethers-provider-bundle 的下载量有多少?

根据 npm 官方下载统计,@flashbots/ethers-provider-bundle 在 2026/10/15 – 2026/11/13 这 30 天内被下载 13,177 次,日均约 439 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@flashbots/ethers-provider-bundle 还在维护吗?

最新版本 1.0.0 发布于 2024/02/06(2 年前);至今共发布 22 个版本,其中过去 12 个月发布了 0 个;首次发布于 2020/12/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。