IOHK官网博客:无意外交易验证之第 2 部分

grafik
原文来自IOHK官网博客Polina Vinogradova,由卡尔达诺大使陈哲Anson翻译

Alonzo交易验证分两个阶段进行,以确保对验证工作的公平补偿

在我们之前的博文中,我们讨论了 Alonzo 分类账上交易和脚本验证的确定性性质,这提供了在交易提交之前可以在本地准确预测链上交易应用程序和脚本验证结果的保证。

依靠 Alonzo 分类账的确定性设计提供的保证,我们实施了特定的两阶段验证方案。它旨在最大限度地减少节点用于验证网络交易的资源,同时消除用户的意外成本。在这篇博文中,我们深入探讨了两阶段验证的工作原理。

在雪莱、阿莱格拉和玛丽时代,交易验证是一个一步过程。有效交易对分类账的影响在应用之前是完全可以预测的。如果交易有效,它就会被包含在一个区块中并添加到分类账中。如果没有,节点将在验证尝试失败后拒绝它,并且交易将不会包含在块中。但是,验证传入交易的节点我们ed 时间和资源,无论交易是否在区块中结束。

Alonzo引入了 Plutus 脚本,与以前的简单脚本相比,这可能需要更多的资源来验证它们。为了解决节点花费资源验证被拒绝的交易脚本的问题,Alonzo 引入了一种两阶段验证方法。该策略保持了将交易应用于分类账的可预测结果,并确保对节点的工作和资源使用进行公平补偿。

两阶段交易验证

Cardano上的交易验证分为两个阶段。引入两阶段验证的主要原因是限制节点未补偿的验证工作量。每个阶段都为实现这一目标服务。粗略地说,第一阶段检查交易是否正确构建并支付其处理费用。第二阶段运行事务中包含的脚本。如果交易是第 1 阶段有效,则运行第 2 阶段脚本。如果第 1 阶段失败,则不会运行任何脚本,并立即丢弃该交易。

因此,即使交易在第 2 阶段无效,节点也应该将可处理的交易添加到区块中。这意味着:

• 节点完成少量无偿工作以发现交易不可处理,但没有完成昂贵的第 2 阶段验证,或

• 交易是可处理的。然后节点可以对脚本执行第 2 阶段验证,相应地将交易标记为第 2 阶段有效或第 2 阶段无效,并将其添加到块中。在任一情况下,节点稍后将通过从该交易中收取的费用或抵押品在验证的两个阶段获得补偿。

期望阶段 2 失败应该很少见,因为提交带有失败脚本的事务的用户将失去 ada 而什么也没有实现。这是局部可预测的,因此是可预防的事件。阶段是必要的保护措施,以保证对脚本潜在的资源密集型计算进行补偿。

让我们仔细看看每个阶段的细节。

阶段1

验证的第一阶段必须简单。如果这个阶段失败,节点就不会因为它所做的工作而得到补偿,因为它不能接受无法处理的交易的处理费用。

阶段 1 验证验证两件事:交易是否正确构建,以及是否可以将其添加到分类帐中。此验证包括以下检查和一些附加检查:

• 它支付正确数量的费用并提供正确数量的抵押品(即在脚本失败的情况下收集的 ada,解释如下)

• 它包括执行 Plutus 脚本所需的所有数据

• 它不超过协议参数中设置的任何界限(输出大小等)

• 其输入是指账本上存在的 UTXO

• 规定的交易计算预算不超过每笔交易的最大资源限制

• 完整性哈希检查等。

在将传入交易添加到内存池(并最终添加到块)之前,节点必须执行所有阶段 1 验证检查。如果这些检查中的任何一个失败,交易将被拒绝,而不会被包含在一个区块中,并且不收取任何费用。在以前的时代,这是唯一的验证阶段,卡尔达诺以这种方式处理所有验证失败。

诚实、不妥协的节点不会故意产生不可处理的交易。节点还可以删除执行阶段 1 无效交易的对抗性传播的连接。

阶段2

验证的第二阶段运行 Plutus 脚本,这在计算上可能更加昂贵。因此,在第二阶段成功或失败后都会收取费用。收集到的 ada 进入费用池,从而补偿节点在验证过程中使用的资源。

成功的第一阶段验证并不能保证所有交易的操作都是可处理的,只有收集抵押品是可能的。 Phase-2 执行 Plutus 脚本验证,并根据验证结果做出是执行完整处理还是仅收集抵押品的决定:

• 完全应用交易(在 Alonzo 之前的唯一可能性)——如果 Plutus 脚本验证了交易的所有操作,或者

• 收集抵押 ada 并忽略交易的其余部分 - 如果 Plutus 脚本之一失败。

回想一下,脚本验证具有本地可预测的结果并保证终止。用户可以在本地检查脚本验证结果,诚实节点之间不会对如何处理给定交易和其中的脚本产生分歧。

抵押

如果脚本没有验证,我们仍然需要补偿节点的工作。但是我们不能只从交易输入中取钱,因为那些可能已经被脚本锁定了—那些失败的!因此,阿朗佐为此引入了一项特殊规定。交易的抵押品是在第 2 阶段脚本验证失败的情况下将作为费用收取的 ada 数量。在可处理的交易中,此金额必须至少是交易费用的某个百分比,在协议参数中指定。

该金额在构建交易时指定,不是直接,而是通过向交易添加抵押输入。与这些特别标记的输入对应的 UTXO 中的总余额就是交易的抵押品金额。这些 UTXO 必须具有公钥(而不是脚本)地址,并且不包含除 ada 之外的其他代币。

仅当任何脚本未能通过第 2 阶段验证时,抵押输入才会从账本 UTXO 中删除。如果所有脚本都通过,则收取指定的交易费用金额,就像以前的时代一样。特别是,金额来自常规的非抵押品输入,抵押品输入被简单地忽略。而且,好消息!允许使用相同的输入作为抵押和常规输入,因为这两组中只有一组会从 UTXO 中删除。

验证抵押投入支出所需的签名在维护交易完整性方面也发挥着重要作用。他们这样做是为了防止对手更改其内容,使其继续可处理但未能通过第 2 阶段验证。这方面的一个例子是对手取代救赎者。进行此类更改需要抵押密钥持有人的签名。如果脚本验证失败,抵押密钥持有者也是唯一将失去任何 ada 的用户。

由于脚本评估是确定性的,抵押密钥持有者能够在签署交易之前在本地检查交易是否会通过链上第 2 阶段的验证。如果是这样,那么他们可以确定它也会在链上这样做,并且他们绝对不会丢失他们的抵押品。善意行事的用户永远不应该丢失他们的抵押品。这也意味着他们可以在多次交易中重复使用相同的抵押品输入,并确保抵押品不会被收集。

现在我们已经启动了 Alonzo 测试网,我们欢迎所有用户和开发人员通过构建和执行 Plutus 脚本来对其进行评估。您可以在专用的 Alonzo 测试网存储库中找到更多信息,或与我们多元化的社区讨论 Plutus 和 Alonzo 主题。

原文链接:No-surprises transaction validation: part 2 - IOHK Blog