IOHK官网博客:Cardano上的无意外交易验证

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

Cardano的 EUTXO 模型支持 Plutus 脚本执行的确定性

随着 Alonzo 硬分叉为 Cardano 带来core Plutus 智能合约功能,分类账不断发展以满足对去中心化解决方案部署的日益增长的需求。卡尔达诺账本设计侧重于高保障、安全和经过验证的形式验证。与此策略保持一致,确保交易处理的确定性也很重要,这意味着用户可以在实际执行之前预测其影响和结果。

随着智能合约支持的引入,保证交易执行成本的能力以及交易在提交之前在分类账上的行为变得更加突出。基于未花费交易输出 (UTXO) 的区块链,如 Cardano,提供了这样的功能。基于账户的区块链,如以太坊,是不确定的,这意味着它们不能保证交易在链上的影响的可预测性。这带来了金钱损失、不可预测的高额费用以及对抗行为的额外机会的风险。

在这篇博文中,我们仔细研究了卡尔达诺的确定性设计的好处,该设计允许在执行前进行安全的交易和脚本评估。在本周晚些时候发布的下一篇博文中,我们将讨论卡尔达诺交易验证的两个阶段。

什么是交易确定性,为什么它很重要?

在交易和脚本处理的上下文中,确定性是可预测性的同义词。这意味着用户可以在本地(链下)预测他们的交易将如何影响分类账的链上状态,而无需:

• 意外的脚本验证结果或失败

• 意外费用

• 意外的分类帐或脚本状态更新。

即使构造正确,确定性系统中的交易也可能会被拒绝。拒绝意味着交易根本无法应用于分类帐,因此对其状态没有影响,因此不支付任何费用。发生这种情况的原因是由于在构建初始交易和处理它的时间之间处理的其他交易导致分类帐更改。即使是简单的交易,这也可能发生。例如,另一笔交易可能花费了用户也计划花费的 UTXO。确定性确保,无论何时接受交易,它只会对分类帐状态产生可预测的影响。

解决不确定性问题

不确定性意味着我们无法预测交易在执行前会对账本产生什么影响。在设计账本和智能合约解释器时,重要的是预见可能发生不确定性的条件,并做出设计决策来避免它们。这种情况下的主要危险之一是访问可变分类帐数据,即可以更改或更改的数据。当交易或智能合约对分类账所做的更改取决于其处理时的状态,而不仅仅是交易的内容时,不确定性可能会成为一个问题。

以太坊特别容易受到这个问题的影响。例如,gas 价格或去中心化交易所 (DEX) 汇率可能会在用户提交交易和交易被处理之间波动。这会导致意外的gas费用或所购买资产的价格变化。或者脚本可能只是失败,导致高执行成本(数百美元)而没有其他影响。例如,如果可用于支付 gas 成本的资金在执行过程中用完,就会发生这种情况。确定性分类帐设计消除了这些可能性。

其他可能的不确定性来源包括允许脚本查看:

• 包含交易但不包含在任何交易中的区块中的数据,例如系统随机性、区块头或当前槽号

• 数据被对手更改或替换,这可能会改变脚本验证的结果,而交易本身仍可处理。

在大多数系统中,有一些方法可以通过改进的脚本编写实践或第 2 层解决方案来缓解这些问题。 Cardano 旨在保证所有脚本和交易的可预测结果。

基本的 UTXO 模型如何在确定性方面受益

Cardano账本建立在 UTXO 会计模型上,这意味着资产存储在账本上的未花费输出中,而不是账户中。这些输出中的每一个都指定了存储在其中的资产数量及其地址。未花费的输出是不可变的,因此交易可能会消耗整个输出,但不能更改它。

为了转移资产,交易消耗一个或多个输出并创建新的输出,这些输出总共包含与消耗的资产数量相同的资产。这些数量 - 及其 UTXO 地址 - 在交易的输出中指定。一笔交易可以影响应用到账本的另一笔交易的效果的唯一方法是花费与后面的交易尝试花费的 UTXO 相同的 UTXO,从而导致节点拒绝它。这是 UTXO 模型依赖于维持确定性的关键特征。

与基于账户的模型相比,UTXO 分类账既有优点也有缺点。例如,后者会遇到较少的事务阻塞实例。与 UTXO 不同,账户是可变的分类账数据。因此,例如,一笔交易可能会看到一个账户中不同数量的资产,这取决于它是在更新同一账户的另一笔交易之前还是之后处理的。这种情况可能不会导致交易被拒绝,但可能会导致分类账发生不同且不可预测的变化。

花费 UTXO 只是交易可以采取的行动的一个例子。接下来,我们解释什么是交易操作,以及如何验证它们。 Alonzo 中引入的最重要的一组更改是对操作验证过程的更改。

使用签名和脚本验证操作

处理交易的一个重要方面是验证它正在采取的行动。当交易在该操作的特定字段中包含数据时,它正在执行操作。例如,当一个交易在其输入字段中包含对 U 的引用时,它正在花费 UTXO U,当它的 mint 字段包含 X 时,它正在铸造一个令牌 X。

当节点处理交易时,它会验证它是否可以执行它打算执行的操作。为此,交易的作者必须提供相关的数据片段,例如脚本、赎回者或签名。需要验证的操作的一个常见示例是使用公钥锁定的 UTXO。交易必须提供来自相应私钥的签名才能执行此操作。

Cardano使用脚本来验证操作。这些脚本是代码片段,使用 True 或 False 输出实现纯函数。脚本验证是调用脚本解释器以在适当的参数上运行给定脚本的过程。

可以为以下操作执行脚本验证:

• 花费由脚本地址锁定的UTXO:运行的脚本是其哈希构成地址的脚本。
• 铸造代币:运行的脚本是其散列构成铸造代币的策略 ID 的脚本。
• 奖励提取:运行的脚本是其散列形成抵押地址的脚本。
• 应用证书:运行的脚本是其散列构成证书作者凭据的脚本。

除了让节点知道要运行哪个脚本之外,所有交易操作都指示如何组合传递给该脚本的参数。

Cardano的多资产分类帐(Mary)支持简单的多重签名和时间锁脚本语言。这些允许用户指定执行操作所需的签名(例如花费 UTXO 或铸造不可替代代币 (NFT)),以及可以执行的时间间隔。时间锁定脚本永远无法看到包含它的交易中的实际插槽编号。时间锁只能看到承载交易的有效期。允许时间锁脚本查看当前的插槽编号(即,数据来自块,而不是作者)会破坏确定性。这是因为用户无法知道处理交易的确切时间段,因此他们无法预测脚本的行为方式。

与 Alonzo 中的 Plutus 合同不同,Mary 脚本的表达内容非常有限。 Alonzo 硬分叉开启了一个强大的、有状态的合约的新时代,这些合约不会损害确定性分类账的属性。

Plutus脚本

由于 Plutus 脚本的实现,Alonzo 在 Cardano 上引入了一种新的交易验证方法。作为 Alonzo 的一部分部署的扩展未花费交易输出 (EUTXO) 模型提供分类账基础架构以支持 Plutus 合约。下面,我们提供分类帐和交易更改的高级概述。有关使用分类帐和 Plutus 脚本的更多详细信息,请查看 Plutus Pioneer 程序!

Alonzo更改分类帐上的数据如下:

  1. Plutus脚本可以锁定 UTXO。

  2. 在 UTXO 的输出部分的内容中添加了一个新组件,可实现类似脚本状态的功能。除了资产和地址,被 Plutus 脚本锁定的 UTXO 还包含一个数据。数据是一段数据,可以被认为是对脚本状态的解释。

  3. 有许多新的协议参数用于对交易施加额外的验证要求。这些包括脚本可以消耗的计算资源的上限。

为了支持 Plutus 脚本,交易已升级如下:

  1. 对于它的每个操作,交易现在携带一个用户指定的参数,称为赎回者。根据脚本,救赎者可以服务于不同的目的。例如,它可以充当用户在拍卖中的出价,或用户在猜谜游戏中的猜测,以及许多其他功能。

  2. 交易为每个脚本指定计算执行预算。

  3. 为确保交易能够支付其执行费用,Alonzo 引入了额外的数据,我们将在后续博客文章中讨论。

  4. 交易包含完整性哈希,需要确保它没有被破坏、过时等。

与 Mary 相比,Alonzo 交易验证的细节也有一些变化。对于每个动作,节点组装 Plutus 解释器期望的脚本参数,包括:

• 基准

• 救赎者

• 执行预算

• 交易摘要。

该节点执行新的、特定于 Alonzo 的检查,以确保正确构建交易。例如,它不得超过最大执行资源预算。它还调用 Plutus 脚本解释器来运行脚本。

基准对象与脚本状态

与可变账户一样,可变脚本状态完全属于不确定性来源的“可变账本数据”类别。我们已经看到 UTXO 模型避免了可变账户的不确定性问题。它还可以帮助我们以保持确定性的方式重新构想脚本状态的概念。如果 UTXO 被 Plutus 脚本锁定,则该 UTXO 的脚本代码与其地址相关联。该脚本的状态模拟是存储在该 UTXO 中的数据。当交易花费该 UTXO 时,它会从分类帐中删除,包括数据。然而,Plutus 脚本的内容可以强制执行携带它的交易还必须创建一个包含特定数据的 UTXO,该数据可以被视为更新的脚本状态。

脚本执行预算

非确定性 gas 模型可以向用户收取不可预测的高额费用。在 Cardano 脚本中,这种不确定性的来源是通过要求将资源预算本身以及支付此预算所需的费用包含在交易中来解决的。在 Alonzo 中,用户可以在构建交易时在本地预测两者。脚本执行必然返回 True 或 False,并且不会无限循环。这样做的原因是脚本执行的每个操作都需要一个非零数量的资源,由解释器跟踪。如果超出交易指定的预算,脚本执行终止并返回 False。

Alonzo中的交易验证

针对不确定性的可能来源,以下关键点使脚本和交易验证的结果可预测:

• 当应用于相同的参数时,脚本解释器将始终终止并返回相同的验证结果

• 交易必须修复将在验证期间传递给脚本解释器的所有参数

• 事务指定它正在采取的所有需要脚本验证的操作

• 交易上的强制签名确保它不会被对手以导致脚本失败的方式改变

• 在 EUTXO 分类帐模型中应用交易是确定性的。

最后一点很大程度上继承自 UTXO 模型,因为 Alonzo 账本协议更新在很大程度上与之前时代的更新(包括委托方案等)保持一致。在 Alonzo 升级之后,脚本验证失败或成功确实会影响交易的处理方式(在第 2 部分中将详细介绍这一点!)。但是,对于给定交易,True 或 False 结果以及与任一结果相关的分类帐更改是可预测的。

Cardano脚本和交易验证的确定性行为不是使用 EUTXO 模型的自然结果。为确保此属性,IOG 团队必须仔细跟踪允许脚本查看的每条数据的来源。

Alonzo规范中正式指定了确定性评估属性,IOG 团队还草拟了证明解释器仅获取不会破坏该属性的参数的证明。

在我们的第二篇博文中,我们将仔细研究卡尔达诺交易的两阶段验证过程。所以,请留意本周晚些时候的第二部分。

原文链接:No-surprises transaction validation on Cardano - IOHK Blog