去中心化的交易所是任何DeFi生态系统的基础。在与WingRiders团队的合作中,我们谈到了如何在Cardano平台上创建这样一个交易所。在这篇文章中,我们研究了一般情况下如何在Cardano上建立应用程序,以及WingRiders团队面临的挑战。看看团队有哪些选择和哪些设计决定是很有趣的。
交易所的演变
集中式交易所(CEXes)仍然主导着数字资产的交易。这些交易所掌握着对私钥、交易所交易参数、用户信息、资金安全、费用和兑换率的控制。这些交易所不能为硬币或代币所有者提供安全的被动收入。
传统的集中式交易所使用所谓的订单簿模式。交易者可以提交他们的买入或卖出订单,由中央做市商进行订单匹配。在买入和卖出订单的匹配过程中,必须遵循一个特定的匹配策略。一旦找到匹配,两个参与者之间的交易就可以被执行。这是用户之间交换两种资产的一个非常基本的概念。
使用订单簿的交易所可以提供两种类型的订单。市场订单允许用户出售代币A以换取所需数量的代币B。用户期望市场订单几乎立即被执行。第二种类型是限价订单,用户以所需数量的代币B卖出代币A,但定义了交易执行的确切价格。因此,限价单可以在较长的时间内待定,直到市场条件接近用户的预期。
去中心化金融(DeFi)给世界带来了不同的交易视角,为用户带来了明显的更好的条件。去中心化交易所(DEXes)提供了一个非托管的解决方案,公平的待遇,较低的费用,匿名性,对每个人的全球可用性,订单的分散和自动化处理,以及利用被动收入的机会。一个完全基本的创新是自动做市商(AMM)模式。
基于AMM模式的交易所通过智能合约的去中心化执行提供资产的自动交易。用户的互换请求完全自动执行,不需要依赖可信的第三方。AMM模式采用了所谓的流动性池。你可以把流动性池看成是两种代币的集合。例如,一个代币A的集合和另一个代币B的集合组成一个流动性池。AMM DEX不需要买方和卖方匹配(没有订单匹配)。相反,用户可以简单地使用流动性池交换他们的代币和资产。因此,互换请求基本上可以立即得到满足。
算法根据流动性池中不断变化的比例来设定代币的价格。用户的互换请求总是被引向一个包含相同代币的特定池子。一个典型的AMM交易所有多个流动性资金池。例如,如果它允许交易代币A、B和C,它可以有3个池。将有3个池子,有以下几对。A和B,A和C,B和C。
为了能够在AMM交易所执行交易,有必要在池子里有足够的代币。换句话说,池子需要足够的流动性。代币持有人可以向资金池提供这种流动性,从而成为所谓的流动性提供者(LPs)。流动性提供者通常为一个特定的池子存入两种类型的代币。这意味着,例如,流动性提供者需要为一个有ADA和代币A的池子存入价值100美元的ADA币和同样价值100美元的A代币。流动性提供者提供代币会得到奖励。奖励与所提供的流动性成正比,并从执行交易的费用中提取。
正如WingRiders团队的一名成员所解释的那样,AMM是去中心化世界中的一种现代交易方式,已经成为新的标准。它是交换加密代币的最便捷方式。随着加密货币采用率的提高,我们可以预期用户会在他们的钱包里例行持有许多类型的硬币和代币,包括比特币和以太坊。这些代币将具有一定的价值,如果用户将代币提供给AMM交易所,就可以获利。交易员和流动性提供者之间存在着一种奇妙的共生关系,两个群体都能从服务的存在中获益。这就是为什么WingRiders DEX将以AMM模式为基础。
了解eUTXO和在Cardano上构建dApps的挑战
在我们看WingRiders设计的一些细节之前,了解Cardano生态系统和Ethereum之间的差异很重要。许多团队试图采取已经在以太坊上运行的DEX并复制其设计,以便在Cardano生态系统中快速构建DEX。这些团队很快意识到这是错误的方法,他们需要对设计进行更多的思考。
VacuumLabs团队为WingRiders DEX的开发提供了动力。该团队在Cardano的生态系统方面有多年的经验,并与IOG团队进行了合作。该团队从一开始就能避免许多错误,并在第一次尝试时就正确设计了DEX。
让我们解释一下Cardano和Ethereum设计之间的差异,以更好地理解团队所面临的挑战。这让你明白为什么你不能只是复制以太坊生态系统的概念。
每个区块链网络都在试图就硬币和代币所有权的变化达成网络共识。换句话说,每个新区块都会更新状态。在区块链行业,有两种普遍的方式来处理硬币。每种方式都有其好处和成本。第一种是未消耗的交易输出(UTXO),它使用比特币。第二种是基于账户的模式,它使用以太坊,但也使用其他项目,如Solana、Polkadot、Algorand等。IOG团队已经实现了UTXO的扩展版本,称为扩展UTXO(EUTXO)。EUTXO促进了智能合约的使用。在本文中,我们将继续使用UTXO这个术语,但在Cardano的背景下,它是EUTXO。
以太坊的基于账户的模式类似于银行账户。硬币存储在区块链地址上,代表当前的余额。每笔交易都会调整余额。当一个用户向另一个用户发送一定数量的硬币时,发送者的账户被递减,接收者的账户被递增。这是一个原子性的操作。
以太坊在所有参与者中保持一个全局共享状态。每个新的交易都会改变全局状态。在每一次改变中,全局状态都被锁定。重要的是要明白,交易是相互依赖的,它们在区块中的顺序很重要。交易的结果具有较高的不确定性,它不是决定性的。为了验证一个区块,有必要知道交易的顺序。交易的验证必须一步一步地进行。因此,并行化是非常困难的,因为新区块中的每一个交易都必须在以前交易的背景下进行验证,并做出改变。
改变全局状态也可以通过执行智能合约来实现,它可以修改余额。以太坊的设计对应用开发者来说有一个优势,那就是不必担心并发性问题。开发人员可以自由地处理用户账户并改变余额。因为保证了余额是单独访问的,所以两个代理同时访问同一个余额的风险较小。因此,设计一个应用程序是相对容易的。缺点是前面提到的并行化的复杂性,经常失败的交易,以及即使是失败的交易也必须支付费用。此外,由于交易的排序,有一个被称为矿工可提取价值(MEV)的问题。
Cardano的EUTXO与以太坊基于账户的模式有很大不同。你可以把UTXO想象成钞票。如果你把你的物理钱包想象成一个区块链地址,你可以在里面有更多的UTXO(更多的钞票)。如果用户想知道一个地址的硬币总数,就需要把所有UTXO的价值加起来。花费UTXO的方式与纸币的方式相同。如果用户有一个价值为100 ADA的UTXO,她需要支付20 ADA,那么20 ADA将离开地址(并将被添加到收件人地址),80 ADA将回到发送人地址。因此,将有两个UTXO(我们忽略了费用)。
从账本的角度来看,一个Cardano交易有输入和输出,其中输入是以前交易的未花费的输出。注意,我们仍然在谈论UTXO。资产被储存在分类账上的未使用的输出,而不是账户(余额)。请记住,每个UTXO只能被消耗一次,并且是一个整体。
在Cardano网络中,交易验证要简单得多。在UTXO模型中,只有本地状态是重要的。这意味着交易的结果只取决于UTXO的使用,UTXO是不可改变的、一次性使用的对象,作为交易的输入和输出。因此,交易是相互独立的,不存在类似全局状态的东西。
最大的优势是,在交易被发送到区块链之前,可以在链外检查交易的有效性。如果交易通过了本地验证(例如在用户的钱包里),那么链上验证也很有可能成功,交易就会进入区块。原则上,一个节点可以并行验证交易,如果这些交易不试图消耗相同的输入。
高水平的确定性和并行化的可能性是Cardano设计的优势。另一方面,正如WingRiders团队的成员所解释的,开发人员必须自己处理并发问题。每个UTXO只能被消耗一次,而且必须经过整个网络的验证。这在技术上意味着UTXO在每个给定的区块中可以被消耗一次。如果交易在同一时间依赖同一个UTXO,就会遇到争夺。如果一些资金被智能合约锁定,在一个区块内只有一个行为者可以与之互动。正如你所看到的,Cardano和Ethereum是两个完全不同的世界。
我们问WingRiders团队,他们在构建DEX方面有哪些选择,以及他们如何在Cardano上与智能合约合作。
在某种程度上,Cardano有点类似于比特币的pay-to-script hash功能,即交易由脚本验证。与比特币不同,在Cardano的情况下,你可以在EUTXO上附加额外的数据(Datum)。Datum是任意的类似JSON的数据。硬币由一个三联体表示:地址、价值和可选的Datum。地址可以来自公钥,也可以是一个脚本的地址。在脚本地址的情况下,只有在相关脚本中定义的验证通过后,UTXO才能被花费。
Cardano允许你在两个不同的部分编写程序逻辑。首先,有一个链上部分,允许写一个验证脚本。脚本是由Cardano节点验证的,所以这部分确保了传统智能合约提供的保证。其次,它是一个链外部分,允许创建一个商业逻辑,以根据相关的链上脚本建立交易。链上和链下的逻辑都可以用Haskell编写。然而,开发人员可以使用任何语言来编写链外部分。
链上和链下部分不一定相互依赖,也不构成一个单元。验证器脚本可以由链外部分创建并定义合约约束。所以,一个UTXO可以被一个不一定由链外部分创建的交易所花费。如果验证脚本中的条件得到满足,那么UTXO就被花费了。正如WingRiders团队的成员所解释的,业务逻辑甚至可以作为软件钱包的一部分来实现,或者与前端的钱包紧密耦合。
在执行过程中,UTXO验证脚本与Datum、Redeemer和包括交易数据的上下文一起操作。正如我们所说,Datum是附在UTXO上的。赎回者是一个用户特定的参数,它是在为花费UTXO而创建的交易中提供的。一般来说,赎回者可以有不同的目的。它可以被看作是用户(交易创建者)对如何花费UTXO的意图。
如何设计DEX
第一个DEX出现在以太坊。开始时,去中心化交易所的流动性很低。这对经典的订单式交易所来说不是一个好情况。最终,引入流动性池的想法开始流行。基于账户的模式很适合,因为流动性池本质上可以只是余额。以太坊允许这些余额在一个区块内被任意改变。Uniswap从AMM概念的成功中获益。
我们问WingRiders团队如何在Cardano上设计DEX,他们需要克服哪些挑战。
在Uniswap中,行为者与流动性池进行互动,原子化地交换代币并更新流动性池的余额。这种简单的设计不能被复制并应用于Cardano。流动性池本质上是一种共享资源,因为多个交易者试图同时使用它。如果流动性池在Cardano中被表示为一个UTXO(一种天真的方式来创建类似以太坊余额的东西),每个区块只能执行一次交换。任何其他尝试都会失败。每次交换后,必须用更新的余额创建一个新的流动性池UTXO。
如何在基于UTXO的账本上进行互换?必须要有一组可以取出代币的UTXO,以及另一组可以插入代币的UTXO。交换可以以这样一种方式实现,即个别交易将从一组中消耗UTXO,并将UTXO插入该组的另一边。互换是通过交换选定的UTXO来实现的。用户必须用一种代币提供UTXO(将留在流动性池中),以获得第二种代币的UTXO。
在这一点上,我们可以看到,我们遇到了Cardano上DEX设计者的挑战。他们必须想出一些业务逻辑,以确保个别演员不会在一个区块内试图使用池中的相同UTXO。这是很棘手的,因为交易是相互独立的。如果没有一些协调或巧妙的算法,用户可能会试图使用同一个UTXO,但只有一个人能成功。设计师的目标很明显。如何在一个区块中实现不同用户与单一流动性池的多次互动。
WingRiders团队的成员继续解释道。我们基本上看到两种策略来解决Cardano中的并发问题:蛮力和批量交易。蛮力策略的可扩展性和使用范围有限。随着整个平台交易的增加,并发问题将成为一个极端的瓶颈。该团队决定使用第二种策略:批量交易。
批量交易策略将与智能合约的互动分成两个阶段。在第一阶段,用户需要创建一个互换请求。当用户签署交易时,UTXO被锁定在脚本地址,包括可以花费UTXO的条件。在第二阶段,轮到代理了(代理也被称为批处理者)。代理人搜索合适的请求UTXO,希望与特定的流动性池互动,以实现请求的互换。有必要满足支出条件。代理人与所有其他可用的互换请求一起做,并将所有的互换插入一个大的批处理中。在创建批量交易时,代理人知道哪些UTXO已经被使用。他们可以确保一个特定的UTXO在一个批处理中不被使用两次。这样的交易会失败,因为一个UTXO只能用一次,所以会被网络拒绝。一旦批量交易得到网络的确认,用户就可以交换他们的代币了。一个很大的优势是直观的用户体验,因为用户在创建交换请求时不会相互竞争,这意味着没有并发问题和更快速的体验。
在第一阶段,还定义了可以取消互换的条件。用户永远不会失去锁定在合同中的资金。互换要么发生,要么不发生,用户可以拿回他的资金。
分批交易模式
让我们更详细地探讨批处理模式。首先,用户需要创建互换请求(包含UTXO),必须提交、结算和确认。这可能需要大约5-30秒。其次,代理可以考虑并收集新的互换请求(交易),只要它们出现在分类账中。代理人创建大批量交易,并有效地利用流动性池一次进行许多互换。
请注意,DEX功能的链外部分是创建DEX交易的任何代码。用户在创建互换请求时利用链外代码。代理在创建批量交易时利用链外代码。
这些批量交易是很大的,因为包含了脚本和大量的输入和输出。代理人的目标是使效率最大化,并包括尽可能多的交换请求。代理人在一次交易中能满足的请求越多,区块链上的负载就越少,整体费用就越低,用户体验的感知也越快。
批量交易也必须提交和确认。确认可能需要另外5-30秒。从创建请求到交换的代币到达你的钱包,总的感知时间可能是15-60秒,但实际上,大部分时间是在等待确认。任何超过这个时间的情况都可能意味着网络可能拥堵,或者代理正在收集更少的请求以减少区块链的拥堵。
要很好地设计批处理模型仍然是一个挑战。如果一个DEX有大量针对单一流动性池的请求,那么批处理需要在区块之间进行排序。这很可能在与单一流动性池互动时造成拥堵,交换等待时间会非常长。这就是我们在最近Twitter上讨论的DEX相关问题中实际可以看到的情况。
让我们看看有什么可以改变和改进的。交易规模可以减少。这并不能完全解决这个问题,但它允许在一个区块中插入更多的交易。同样地,智能合约的资源使用也可以减少。智能合约的实施越是优化,越是可以在区块中插入更多的智能合约交易。
致力于优化是每个开发团队的目标,DEX也不例外。由于交易量可以快速上升,拥有良好的优化实施是至关重要的。幸运的是,WingRiders团队拥有非常有经验的Haskell开发人员。从一开始到主网,专注于优化是团队的首要任务。
拥有更多的代理和流动资金池通常是总用户的一个函数。一个受欢迎的DEX会吸引更多的用户。这意味着DEX对流动性提供者更有吸引力。拥有大量的用户可以创建更多具有相同配对的流动性池。因此,互换请求可以更好地分配给池子。拥有更多的代理是困难的。WingRiders从一开始就为任何用户提供了成为代理人的机会。这是一个复杂的工程问题,但团队非常了解它,而且我们已经在浏览器中运行了一个概念验证。
交换的速度
交换速度对用户来说是一个非常重要的因素。WingRiders DEX的优势之一将是交换的速度。注意,感知的dApp速度取决于许多因素,包括内部和外部因素。为了掌握这一点,让我们把它分解并重新组合起来。每个dApp都在分布式网络环境中运行,有自己的属性和特点。dApp并不存在于真空中,可能有许多其他dApp在平行运行。为了能够为用户提供流畅的用户体验,dApps也会使用反映区块链状态的基础设施,甚至操作一些商业逻辑或流程。基础设施还引入了延迟。这些都是外部因素。
区块时间是区块链的一个属性,它是外部因素。目前,Cardano已经将该值设定为20秒。交换速度部分受到区块时间的影响,但有许多参数可能对整个网络的吞吐量(处理的用户请求的数量)产生影响。如果交易不适合在区块中,它们必须等待更长的时间才能纳入。目前Cardano的一些参数是保守设置的。影响dApp速度的其他重要参数是区块大小、最大交易规模限制、每笔交易的Plutus脚本内存单位等。
IOG团队已经表现出增加参数的意愿。每个参数的变化都是经过仔细考虑,然后由团队观察。根据观察的结果,计划进一步的更新。IOG团队试图尽可能地满足用户和开发者的要求。
在写这篇文章的时候,一个区块可以包含大约4个最大尺寸的交易或大约250个小交易。在现实中,在区块中两者都有混合。大概是每分钟12-800个交易。如果一个区块中的所有交易都是脚本交易,那么对于一般的DApps来说,这个范围将缩小到每分钟12-72个交易。现实上,对于具有较大脚本的交易,每分钟将有大约20个dApp交易。
在一个典型的区块中,可能会有几个大的交易加上更多的小交易。随着网络利用率的提高,区块中的最大空间被理想地占据。如果一个区块中总是有很多大的(脚本)交易,而小的交易无法通过,这可能导致更多的堵塞。
考虑到这些数字是稍微悲观的近似值,因为Cardano上的智能合约仍然处于早期阶段。许多改进已经被提出来了。优化可以在DApps开发方面进行,WingRiders团队不断地改进设计。
处理交换请求的数量取决于智能合约的交易规模、内存和cpu使用率。这时,dApp设计的内部因素、并发解决方案和权衡变得很明显。
WingRiders团队在公共的Cardano测试网络上做了一个测试。在10个区块中,代理满足了175个交换请求。如果区块每20秒创建一次,那么结果将相当于每分钟满足约55个请求。所有这些在测试期间都有其他DApps存在。从这个角度来看,根据最近的交易数字,Uniswap v3更接近于每分钟20-40个操作。
交换请求的排序很重要
用户以特定的顺序提交他们的交换请求。代理人能够在账本中找到这些请求并满足它们。WingRiders保证用户提交的互换请求的顺序将被代理所尊重。顺序的执行是为了确保先来后到原则的公平性。
代理被期望公平地找到给定流动性池的最古老的互换请求。一旦交换请求被选中,尊重交易规模限制和脚本执行单位,批量交易就被创建。注意,即使在这些批量交易中,排序也是至关重要的。想象一下下面这个非常简单的批量交易,它只包含两个互换订单。
Alice将10,000,000 BTC换成ADA,这导致了巨大的滑点
布莱恩将10个ADA换成BTC
当Brian在Alice的交换完成后交换他的10 ADA时,由于Alice造成的滑点,他将得到更多的BTC。然而,当Brian的交换在Alice的交换之前完成时,他得到的将会少得多,但这不会对Alice产生巨大的影响。请注意,就用户的满意度和公平性而言,顺序是很重要的。
你是否记得,在Cardano网络上没有类似全局的状态,交易的顺序并不重要?所以,对于智能合约的能力也是如此。开发人员在设计应用程序的逻辑时,必须考虑到这一点。
交易建立者(在代理的代码中实现的链外部分)知道需要履行交换的顺序。但即使代理知道正确的顺序,情况也不是那么简单。根据设计,与区块中的交易类似,交易中的输入顺序没有特别的意义。
为了遵循WingRider的设计并确保承诺的公平性,必须有一个机制来管理输入的正确顺序。为了确保这一点,采用了插入Redeemers的指数。在交易中把一个特定的输入放在前面是不够的,在交易可以被验证器读取之前,输入会被排序为不同的顺序。这意味着,如果没有Redeemers中的额外索引,验证器就不能知道哪个输入(哪个请求)要先执行,哪个要后执行。
所以,交易生成器将Alice的输入先插入交易中,并将赎回者分配到索引0。这表明它应该被首先执行。类似地,Brian的赎回者将被设置为索引1。指数帮助验证器找出哪个交易输入(交换请求)要先执行,哪个要后执行。
如果没有所描述的带有索引的附加逻辑,验证器将无法确保交换请求真的以正确的顺序得到满足。换句话说,有必要创建额外的逻辑来维持所需的顺序,因为Cardano不能在交易和它们的输入层面上提供这个。
WingRiders希望确保所有的交换都按照用户创建的顺序完成,这是一个原因。除了公平性,还有必要验证所有用户都得到了正确的补偿。如果没有,验证就会失败。团队不想因为合同不能依赖输入顺序而对智能合同内部的计算精度做出妥协。我们设计了一种方法,让代理人即使在交易内部也能确保排序。
网络效应是成功的关键
每个服务都需要用户。这对DEX尤其重要,因为用户数量越多,流动性越高,服务就越好。WingRiders是一个AMM交易所,所以它需要两种用户。想交换代币的用户。其次是想使用他们的硬币或代币以获得奖励的流动性提供者。用户需要为交换付费,而收集到的部分费用则用于奖励流动性提供者。该经济模式是功能性的,因为两组用户的利益得到了满足。
服务的用户界面和可及性是至关重要的。由于WingRiders在Cardano项目及其基础设施方面的丰富经验,这是WingRiders的一大优势所在。该团队的目标是使WingRiders成为一个核心的基础设施元素。这将通过非常容易集成到任何钱包或DApps的可能性来实现。该团队非常了解如何做到这一点,因为他们在过去创建了流行的Adalite钱包,现在正在开发一个名为NuFi的新钱包(一个钉子户平台,计划支持10个区块链)。该团队还致力于将Cardano钱包与Trezor和Ledger HW钱包整合。WingRiders将是一个非常模块化和灵活的软件,适合整合。这是一个有效的策略,可以更接近用户,扩大网络效应。
如何满足用户
每个团队必须仔细考虑应用程序的设计,为用户提供有吸引力的功能,并保证特定的功能。
服务的安全性是获得用户信任的绝对关键特征。WingRiders将让外部审计人员(即CertiK)检查源代码,以确保发送到交易所地址的硬币和代币永不丢失。用户和流动性提供者可以确信他们的资金不会丢失。对高安全性的强调符合Cardano项目的理念,安全审计几乎是成功的必要条件。
WingRiders向用户承诺,掉期将按照规范的顺序执行。没有理由给任何人好处。所有用户都将被平等对待。
团队正在努力使DEX对所有用户都尽可能的方便。费用是决策的一个重要部分。通过优化,团队能够减少使用Cardano网络的费用规模。这将减少WingRiders终端用户的费用。
简易性和清晰度是成功的其他重要要求。用户界面是该团队的优先事项之一。如前所述,WingRiders与钱包和DApps的整合将非常容易。这在他们的测试网络版本中已经可以看到,其中显示了与钱包(NuFi)的深度整合。
除了为资金池提供流动性而获得奖励的可能性外,该团队还寻求保留参与ADA币的盯盘能力,从而不会错过盯盘奖励。
Cardano生态系统正在迅速发展,WingRiders交易所的第一个版本可能不是完全最佳的。团队将反映Cardano基础设施的演变,并相应调整DEX。
结语
这篇文章的目的不是为了比较Cardano和Ethereum架构。这两个平台在本质上是不同的,并且会找到自己的应用。通过WingRiders团队,我们想告诉你在Cardano网络上构建DEX是多么复杂和具有挑战性。除了基本概念外,几乎没有任何东西可以从以太坊世界中获取,团队必须提出全新的想法。
WingRiders有一个强大而有经验的团队,资金充足。DEX已经在测试网络上运行,并将于2022年第一季度出现在Cardano主网上。请务必随时来尝试交换或提供流动资金。你可以查看项目的官方网站或在Discord上与团队聊天。