本文介绍了Base Flashblocks技术,它通过将传统区块分解为迷你区块,以200毫秒的间隔提供交易预确认,从而显著提高去中心化应用的用户体验。
缓慢的交易确认时间可能是去中心化应用程序中用户体验的一个主要障碍。Base Flashblocks 提供了一个强大的解决方案,可以在短短 200 毫秒内提供交易预确认——比Base标准的 2 秒区块时间快 10 倍。这项技术将传统的区块分解为每 200 毫秒流式传输的 迷你区块,在保持加密安全性的同时提供近乎即时的交易反馈。
在本指南中,我们将构建一个可视化比较 dApp,演示使用 QuickNode 支持 Flashblocks 的端点来实际展示这种速度差异。以下是应用程序和控制台输出的样子:
在我们的示例应用库中探索更多
此示例应用也出现在 QuickNode 示例应用库 中。查看它以获取更多即用型 Web3 项目、工具和灵感,以启动你的下一个构建!
Flashblocks 通过提供比传统区块创建快得多的预确认层,从根本上改变了 Base 上交易的处理方式。无需等待 2 秒的L2标准区块,Flashblocks 每 200 毫秒流式传输更新,提供几乎即时感觉的用户体验。
为了进行技术深入研究,我们强烈建议观看我们详细的视频说明。就本指南而言,我们将介绍你需要了解的核心概念。
有关 Flashblocks 架构和实施细节的技术深入研究,请观看此视频。
QuickNode
QuickNode
在 YouTube 上观看 / 订阅我们的 YouTube 频道以获取更多视频!订阅
每 200 毫秒,创建一个新的 flashblock,其中包含待处理的交易。这些不仅仅是状态更新 – 每个 flashblock 代表着区块链状态在当时具有加密安全性的快照。
十个 flashblock 在 2 秒内逐步累积以形成一个完整的区块。这意味着虽然最终区块仍然需要 2 秒才能生成,但用户在此期间会获得 10 次确认更新,而不是等待整个持续时间。
来源:QuickNode Youtube 视频 - Flashblocks Explained
Gas 在这十个 flashblock 中逐步分配。第一个 flashblock 具有较小的 gas 限制 (1.4M),随着每个后续的 gas 限制增加,直到在最终 flashblock 中达到完整的区块 gas 限制。这允许较小的、时间敏感的交易能够快速确认。
来源:QuickNode Youtube 视频 - Flashblocks Explained
每个 flashblock 都包含其自身的状态根,从而确保每 200 毫秒间隔进行加密验证。这在提供更快反馈的同时保持与传统区块相同的安全保证。
在累积 10 个 flashblock 后,完整的区块将提交到 Ethereum L1 进行最终结算,从而确保与传统 Base 区块相同的最终性保证。
这种设计允许应用程序更早地看到状态变化并快速更新 UI,而无需等待完整的区块周期。
Flashblocks 与现有的标准 RPC 方法无缝集成,但有一些需要注意的差异。虽然某些方法必须与 pending
标记一起使用,但其他启用 Flashblocks 的方法可以在没有它的情况下调用。
方法 | 描述 | Flashblocks 用法 |
---|---|---|
eth_getBlockByNumber |
按编号检索区块 | 使用 pending ,返回最近的 Flashblock |
eth_getTransactionReceipt |
获取交易回执 | 返回 Flashblocks 中预确认交易的回执 |
eth_getBalance |
查询账户余额 | 使用 pending ,反映来自最新 Flashblock 的余额变化 |
eth_getTransactionCount |
获取账户 nonce | 使用 pending ,返回来自 Flashblocks 的最新 nonce |
eth_getTransactionByHash |
按哈希检索交易 | 返回具有指定哈希的交易 |
有关 RPC 方法的更详细分解,请参阅我们的 Flashblocks 文档。
关于 eth_getTransactionReceipt
和 eth_getTransactionByHash
的重要说明
使用 eth_getTransactionReceipt
和 eth_getTransactionByHash
方法时需要注意的一个关键行为是,在启用 Flashblocks 的端点上,这些 RPC 调用将始终返回预确认的数据。
与其他 Flashblocks 支持的方法不同,这些方法不接受区块标签参数(如 pending
或 latest
)。这意味着你不能使用它从 Flashblocks 端点获取传统的确认的回执。
QuickNode 在 Base Mainnet 和 Base Sepolia 测试网上都支持 Flashblocks。在本指南中,我们将使用 Base Sepolia 作为示例,但 Base Mainnet 的过程是相同的。
你的 dApp 或脚本需要使用相关的 RPC 方法的 pending
区块标签正确配置才能与 Flashblocks 交互。Viem 提供了几种实现此目的的方法,并且由于 Wagmi 在底层使用 Viem,因此为你的 dApp 集成 Flashblocks 与配置链一样简单。
显式地用于每个方法: 你可以手动将每个单独方法调用上的 blockTag
设置为 'pending'
(例如,client.getBalance({ ..., blockTag: 'pending' })
)。这提供了细粒度的控制,但可能会重复。
在客户端上设置: 你可以在使用 experimental_blockTag
属性创建 Viem 客户端时设置默认的 blockTag
(例如,createPublicClient({ ..., experimental_blockTag: 'pending' })
)。这会将设置应用于使用该客户端实例进行的所有方法调用。有关详细信息,请参阅 此处。
使用预配置的链(推荐): 最方便的方法是使用已内置预确认机制的链配置,例如 baseSepoliaPreconf
。这会自动将默认区块标签设置为 pending
,而无需额外的配置。
对于此项目,我们使用 Viem 的 baseSepoliaPreconf
链。此配置自动确保相关的 API 调用从最新的 flashblock 而不是上次最终确定的区块中获取数据。
当使用像 baseSepoliaPreconf
这样的配置时,pending
区块标签会自动应用于几个关键的 Viem Actions 的默认值,包括:
call
estimateGas
getBalance
getBlock
simulateContract
waitForTransactionReceipt
watchBlocks
有关最新信息,请始终参考官方 Viem 文档。
在此应用程序中,我们将运行两个客户端实例,一个用于传统区块,一个用于 flashblock。然后,我们将使用 getBlock
方法来查看交易何时包含在区块中,并使用 getBalance
方法来获取更新的余额。
让我们设置开发环境并使比较 dApp 在本地运行。
git clone https://github.com/quiknode-labs/qn-guide-examples.git
cd qn-guide-examples/sample-dapps/flashblocks-base
pnpm install
## or
npm install
## or
yarn install
复制示例环境文件:
cp .env.example .env.local
使用你的凭据编辑 .env.local
:
NEXT_PUBLIC_QUICKNODE_ENDPOINT=your_quicknode_endpoint_here
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id_here
pnpm dev
## or
npm run dev
## or
yarn dev
导航到 http://localhost:3000
以查看正在运行的应用程序。
Flashblocks 应用程序已准备就绪。现在让我们探索使并排比较起作用的核心实现细节。
比较逻辑的核心在于使用两个不同的 Viem publicClient
实例。你可以在 /lib/clients.ts
文件中找到此配置。此设置的关键在于我们用于每个客户端的 Viem 链配置之间的差异:baseSepoliaPreconf
和 baseSepolia
。
baseSepoliaPreconf
(对于 Flashblocks):这是 Viem 提供的专门为 Flashblocks 设计的特殊配置。此链配置具有预确认机制,因此,Viem 会自动将 RPC 请求的默认区块标签设置为 pending
。
baseSepolia
(对于传统区块):这是 Base Sepolia 测试网的标准配置。它使用 latest
的默认区块标签。
// lib/clients.ts
import { createPublicClient, http } from 'viem'
import { baseSepolia, baseSepoliaPreconf } from 'viem/chains'
const QUICKNODE_ENDPOINT = process.env.NEXT_PUBLIC_QUICKNODE_ENDPOINT!
// Flashblocks 客户端自动对支持的操作使用“pending”
export const flashblocksClient = createPublicClient({
chain: baseSepoliaPreconf,
transport: http(QUICKNODE_ENDPOINT),
})
// 传统客户端默认使用“latest”
export const traditionalClient = createPublicClient({
chain: baseSepolia,
transport: http(QUICKNODE_ENDPOINT),
})
我们将从两个客户端获取初始余额并在应用程序中显示它们。这在 use-balance-tracker.ts
hook 中完成。
// hooks/use-balance-tracker.ts
// ...
const client =
clientType === 'flashblocks' ? flashblocksClient : traditionalClient
const newBalance = await client.getBalance({ address })
setBalance(newBalance)
// ...
交易确认策略在 use-transaction-tracking.ts
hook 中管理。对于此演示,我们没有使用 Viem 的 waitForTransactionReceipt
,而是实现了一个自定义轮询机制来高亮显示区块可用性的差异。
以下是流程:
getBlock
。此轮询实现旨在通过将每次试验记录到控制台来有效地演示该概念。对于生产应用程序,你应该使用更强大的方法,例如 waitForTransactionReceipt
以确保交易的最终性。
以下是轮询循环的部分代码:
// hooks/use-transaction-tracking.ts
// ...
try {
// 获取包含交易的最新区块
const block = await client.getBlock({
includeTransactions: true,
})
console.log(
`[${clientName}] Checking block ${block.number} (${block.hash}). Attempt: ${attempts}`
)
// 检查我们的交易哈希是否在区块的交易中
const txInBlock = block.transactions.find((tx: any) => tx.hash === hash)
if (txInBlock) {
confirmed = true
confirmationTime = Date.now() - startTime
// 获取完整的收据以获取更多数据
receipt = await client.getTransactionReceipt({ hash })
console.log(`[${clientName}] Tx ${hash} confirmed in block ${block.number}`)
break
}
// 等待下次尝试
await new Promise(resolve => setTimeout(resolve, 100))
} catch (blockError) {
console.warn(`[${clientName}] Block fetch attempt failed:`, blockError)
// 继续尝试
await new Promise(resolve => setTimeout(resolve, 100))
}
// ...
现在让我们看看 Flashblocks 的实际效果。按照以下步骤测试应用程序:
连接你的钱包:确保你的开发服务器正在运行。单击应用程序中的 连接钱包 按钮,然后在你的浏览器钱包中批准连接。确保你已连接到 Base Sepolia 网络。
获取测试 ETH:如果你需要 Base Sepolia ETH,请访问 QuickNode 的 Base Sepolia 水龙头 并输入你的钱包地址。你将收到用于交易的测试 ETH。
发送测试交易:单击 发送 0.0001 ETH 测试交易 并在你的钱包中确认交易。你可以观看两个面板以获取确认更新。
你应该观察到 Flashblocks 面板(左侧)比传统面板(右侧)更新更快。更新应该是近乎即时的。你还可以查看控制台日志以获取轮询机制。
关于确认速度的说明
有时,你可能会注意到 Flashblocks 面板未显示已发送交易的确认时间。发生这种情况的原因可能是 Flashblocks 速度非常快,以至于交易可能在应用程序的简单轮询循环开始检查之前已包含在区块中。
这是演示的 getBlock
轮询方法的一个细微差别。在生产应用程序中,使用更强大的功能(例如 waitForTransactionReceipt
)将可靠地捕获交易确认。
本指南中 Techniques 使用的技术旨在清楚地Demonstrate Flashblocks 的速度。在构建生产应用程序时,请记住以下注意事项:
使用 waitForTransactionReceipt
用于生产代码:我们的演示中使用 getBlock
进行手动轮询是为了实现可视化。在真实的 dApp 中,你必须使用 Viem 的 waitForTransactionReceipt
函数。它更高效、更强大且针对生产用途进行了优化,可在内部处理重试和轮询。此外,如果你需要等待特定数量的确认,请使用 confirmations
标志。
区分预确认和最终性:Flashblocks 以毫秒为单位提供高可信度的 预确认。这对于用户体验来说非常棒。但是,它与链上最终结算不同。对于关键交易,你可以等待交易在后续区块中完全最终确定,以防止区块重组等罕见情况。
优化你的数据获取:我们的演示每 100 毫秒轮询一次,以查看 Flashblocks 的效果。你可以根据你的用例选择相关操作中的轮询间隔。此外,对于需要绝对最低延迟更新的应用程序,你可以考虑使用 WebSocket (WSS) 连接。请注意,QuickNode 上的 WSS 连接尚不支持 Flashblocks。
你学习了 Flashblocks 的工作原理,如何配置 Viem 以通过预定义的链使用它们,以及如何构建比较 dApp 以亲身体验这些好处。通过将 Flashblocks 与 QuickNode 集成,你可以显着增强 dApp 的用户体验,从而提供用户期望的速度和响应能力。
我们很乐意听到更多关于你正在构建的内容。在 Discord 中给我们留言,或者在 X 上关注我们,以了解所有最新信息!
如果你对新主题有任何反馈或要求,请告诉我们。我们很乐意听取你的意见。
- 原文链接: quicknode.com/guides/oth...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!