以太坊交易可能发生的8件事以及如何在Dapp中进行导航

保险丝

在上一篇文章中,我们介绍了以太坊节点的固有限制以及这些限制对开发人员的一些限制,并介绍了dfuse平台如何提供帮助。在本文中,我们将重点介绍以太坊交易的复杂生命周期,以及当您尝试在dapp中提供出色的用户体验时所带来的挑战,以及dfuse如何提供帮助。

每当将交易提交到以太坊网络时,它就会以相当复杂的方式通过一系列状态进行。并非每个状态转换都向前移动-事务可以退回到较早的状态,可以被另一个事务替换,或者可以完全分叉。 (我们将在本文后面详细介绍交易的生命周期。)

使用dfuse毫不费力地跟踪交易状态在dapp中跟踪交易过程并向用户提供良好的体验可能会非常困难。如今,许多基于以太坊构建的dapp都为用户提供了诱人但静态的用户体验,这些体验显示了某个时间点的交易状态,因此必须刷新(通过用户点击Refresh或dapp UI定期刷新页面) )以获取更新。其他人则提供了更多的动态接口,但只能用相对粗略的粒度来做到这一点,并且/或者以高网络流量为代价,并在其底层区块链节点上施加高负载。

在这篇文章中,我们将讨论造成这种情况的原因,然后讨论如何在dapp中提供现代且流畅的用户体验,细粒度的事务状态更新以及以高效网络和服务器高效的方式。

每个dapp都需要向用户显示有关dapp正在执行的基础区块链交易的信息-无论是以太坊转移,代币转移还是智能合约方法调用。

如今,许多dapp具有界面风格,在这种界面风格中,每当向用户显示有关其底层区块链操作的信息时,该信息便会在单个时间点(即页面显示的时间)反映出区块链的状态。

用户在交易的整个生命周期中经常需要更新的信息(例如,知道何时完成转移),因此dapp提供了“刷新”或“更新”按钮(或为用户自动执行相同的页面刷新) ),或者用户使用其浏览器的“刷新”按钮重新显示该页面。

一些dapp更进一步,并向用户显示动态交易更新。为此,他们通过在页面后台轮询AJAX请求,反复检查其以太坊节点以获取更新,然后将更改发布到前端。这非常复杂,因为dapp必须进行许多API调用,查询许多不同的数据源(包括块,内存矿池和网络条件),以便跟踪事务的生命周期直至完成。

这种方法还产生了一个折衷方案-交易更新不频繁且粗粒度,这使用户感到沮丧并诱使他们无论如何都要单击“刷新”以获得更快的更新-或dapp必须高频次轮询链条,从而产生大量网络流量并在底层区块链节点上施加高负载。

对于dapp开发人员而言,静态页面或轮询是最佳的可用选项,这一事实反映了以太坊节点提供的API的性质。一个事件驱动的界面可以接收从区块链推送的交易更新并实时向用户反映,这将提供更好的体验-但是标准的以太坊节点并非旨在提供丰富的实时流交易数据。

以太坊节点确实提供了有限的事件流功能。这些事件流仅通过以太坊的JSON-RPC接口的PUB / SUB功能可用(在使用GraphQL时不可用)。 PUB / SUB接口允许dapp订阅以接收一些事件类型的通知:

  • newHeads-每次将新的块头附加到链上
  • 日志-包含在新导入的块中并与给定过滤器匹配的日志
  • newPendingTransactions —添加到挂起状态并使用节点中可用密钥签名的所有事务的哈希(在公共节点上很少见)
  • 同步—指示节点何时开始或停止同步

(有关详细信息,请参见此处)

这些事件类型太受限制,无法使dapp在其生命周期内跟踪事务。

以太坊交易具有复杂的生命周期。每个事务都经过多个定义的状态,并在通过状态前进(或后退)时经历各种状态转换。

交易状态

从首次提交到网络直到以太坊交易(可能)包含在链中的一个区块中,以太坊交易会经历一系列状态。这些状态如下:

  • 未知:网络未看到或未处理的交易将处于未知状态。
  • 待处理:等待矿工选择和处理的事务处于待处理状态。它们位于所谓的内存矿池中。矿工通常会首先选择天然气价格较高的交易,因此天然气价格较低的交易可能会长期处于PENDING状态。汽油价格最低的交易可能永远都不会被拾取,这将导致它们无限期地处于“挂起”状态。
  • IN_BLOCK:当矿工成功选择交易并将其在一个区块内开采时,交易将进入IN_BLOCK状态。一旦输入了IN_BLOCK,如果分叉该块,则事务可能会回到PENDING状态。
  • 已替换:发生以下任一事件时,事务可以从“挂起”状态移至“已替换”状态:
  • 来自相同发件人的相同发件人的另一个事务进入IN_BLOCK状态,或者
  • 来自同一发件人,具有相同随机数且汽油价格高出12%的另一笔交易进入“待处理”状态
  • 下图显示了这些状态以及它们之间的过渡。

    下图显示了这些状态及其之间的转换。

    如上图所示,状态之间的转换也具有名称。

    • POOLED:处于未知状态的事务进入等待矿工选择的事务矿池,被称为POOLED并进入PENDING状态。如果替换条件不再成立,则处于替换状态的交易也有可能再次变为POOLED(例如:在极少数情况下,以IN_BLOCK的低油价交易被分叉,并且具有替换价的交易被替换为POOLED)汽油价格较高的随机数+发送方仍在浮动)。
    • 已开采:已开采交易是由矿工处理过的交易,创建了一个区块。一旦被挖矿,就说事务处于IN_BLOCK状态。由于以太坊网络的点对点性质,从给定节点的角度来看,事务可以从UNKNOWN状态直接移动到IN_BLOCK状态,而无需明显地通过PENDING状态。出于相同的原因,从给定节点的角度来看,事务也可以从REPLACED状态转换为IN_BLOCK状态,而不通过PENDING状态。
    • REPLACED:从PENDING状态转移到REPLACED状态的事务被称为REPLACED。有关发生这种情况的信息,请参见上面的REPLACED状态。
    • FORKED(叉):当一个已挖矿的事务(即处于IN_BLOCK状态的事务)是被网络反转的块的一部分时,就会发生一个叉事务。随后将对反向块内的所有事务进行分支,从而将它们从IN_BLOCK状态移动到PENDING状态。
    • 确认:每次挖矿后续子块时,都会确认处于IN_BLOCK状态的事务。

    如您所见,以太坊事务的生命周期可能非常复杂,这使得dapp难以准确跟踪它并向其用户提供无缝更新。

    使用dfuse轻松跟踪交易状态

    dfuse平台为您提供了一个丰富的流接口,该接口支持实时详细跟踪以太坊交易的生命周期。 dfuse以太坊状态跟踪器API使开发人员能够提交以太坊交易,然后随着交易在其整个生命周期中的进展,在同一通道上提供即时和精细的更新。

    使用GraphQL,您可以实时订阅特定事务的转换,并可以精确指定每次转换要接收的数据。 dfuse平台管理通过其各种状态转换来跟踪事务的复杂性,并在事件发生时实时将事件流传输到dapp。

    结果是,您无需实施复杂的后台逻辑即可重复轮询更新,也无需浪费带宽和处理重复查询。您可以简单地订阅所需的更新,然后在用户界面中反映这些更新。

    下面的动画显示了一个经过复杂生命周期的事务-它经历了八个状态转换,最后才被包含在块中并得到确认。

    如果您未使用dfuse,则dapp必须重复轮询链以捕获事务经历的所有转换以更新用户,并且您的代码需要准备好以对每个转换进行适当响应。

    使用dfuse,您的dapp只需要侦听单个连接上的流更新,因为dfuse会为您跟踪曲折,直到交易的命运最终确定。

    Lifecycle API只是dfuse平台的一小部分,但很重要。 dfuse为您的dapp提供了一个完整的现代化基础架构层,即:

    • 快速,
    • 可扩展
    • 为您提供对区块链事件的高度精细的流式访问,
    • 支持活动的Webhook风格的回调,
    • 具有业内最高的可靠性。

    立即尝试dfuse。如有任何疑问/建议,请通过Twitter或电子邮件与我们联系,或谈论您对以太坊dapp的构建经验-我们很想知道您是否对这项服务感到满意。

    你可能还喜欢