N Chainz:一种去中心化、高性能加密货币交易所

跨链一直是很热门的技术方向,因为单链性能会是未来区块链的瓶颈,跨链是提高区块链扩展性的一种解决方案,并且不同区块链上的价值交换也需要跨链方案来解决,跨链头部项目有cosmos和polkadot。

本文采用了一种跨链解决方案,基于该解决方案实现了一个去中心化的交易所,虽然是两年前的产物,思想也值得研读一下。我对原文做了翻译,内容如下:

译者简介:
朱月俊,百度超级链核心开发者,翻译《启示录:如何打造用户喜爱的产品》第二版

百度超级链:https://github.com/xuperchain/xuperunion

大家觉得不错的话,欢迎点star并提供pr。

我会持续翻译区块链前沿技术文章,与大家共享科技带来的快感!!欢迎大家关注我的新浪微博:朱月俊-区块链

 

N Chainz:一种去中心化、高性能加密货币交易所

Nick Egan         Ryan Senanayake        Lizzie Wei

原文链接:https://github.com/RSenApps/nchainz/blob/master/NChainzWhitepaper.pdf

 

1引言

中心化交易所假定交易所财产所有者会采取安全预防措施。事实并非如此,已经发生了多起中心化交易所加密货币被盗事件,总计造成数十亿美元的损失,这给去中心化交易所留下了很多空间。去中心化的交易所有可能更安全:从理论上讲,用户不会遭受服务器停机和黑客攻击问题,同时用户能够匿名交易。

我们提出了一种去中心化的加密货币交易所N ChainZ。具体来说,N ChainZ的功能包括区块生成,限价订单以及不同链的token互相交易。我们关注的重点是高性能以及容错能力。理想情况下,我们会构建一个高性能的去中心化交易所,不过即使构建一个高性能的中心化系统也是一个相当复杂的问题。N Chainz不依赖任何框架。我们相信,我们的设计能够兼顾简单与性能。本文,主要讨论关键设计选型与实现。

N Chainz:一种去中心化、高性能加密货币交易所_第1张图片

图1:系统框架概览N Chainz架构分为多层,我们将在接下来的几节中详细讨论。

2 多链

我们设计中最独特的地方是使用多链来达到全局共识。为每一个添加到交易所的token维护了一条单独的链,同时维护一条撮合链,用于撮合不同链上的token交互。与单链相比,这种设计有很多优势,后续会展开讨论。

2.1 与单链的对比

多链提供了扩展能力。在单链的设计中,性能与token交易数量成反比关系,因为所有节点的状态必须达成一致。我们的设计允许每条链独立运行,由撮合链对交易强制达成共识。我们假定不同链上的token交互命令不频繁(例如交易订单),单个区块链内部的token交互命令比较频繁(例如转账)。

在我们的原型中,矿工可以随机选择一条链打包区块,不过随着系统规模变大,矿工会倾向于选择一些特定的链打包区块(所有的矿工都必须竞选撮合链上的出块权)。这可以将整个区块链分切到多个矿工集合中,从而节省数据存储成本,不同链内的token转账性能还互不影响。即使所有矿工都必须竞选撮合链的出块权,撮合链仍然是最节省存储空间的,因为撮合链上的交易本质上都是其他链交易的hash值信息(参考2.3小节)。这也意味只需要少量信息就能达成全局一致(在我们的系统中,撮合链的交易大小通常为56字节,比特币的交易大小通常为250字节),理论上,更少的信息能够提供更大的系统吞吐。

大多数区块链系统的瓶颈是网络延迟和带宽。如果对等网络延时较低,则可以通过降低出块难度从而加快出块时间,而如果带宽比较大,则可以增加区块大小。在单链系统中产生一个区块后会在网络上反复传播,从而产生泛洪效应,这会增加区块传播延时并导致带宽利用率下降。我们认为一个多链系统中,由于每个区块链在不同的随机时间达成共识,可以提高系统网络利用率。链与链之间的分叉概率低于链内分叉概率(由于多链共识机制),因此从理论上讲,我们可以进一步降低挖矿难度,提高区块大小从而获得比单链更高的吞吐。

N Chainz:一种去中心化、高性能加密货币交易所_第2张图片

图2:N Chainz使用多链来存储系统状态(如图所示:一个撮合链以及两个token链)。撮合链对不同链的token交互订单进行排序,并由orderbook和Unclaimed Funds进行订单撮合。根据资金流向描述交易类型。

虽然该系统有它的优势,同时也有一些问题需要解决。第一个问题是hash算力被均摊到多链之间,导致每条链更容易受到51%攻击。不过,此系统同时提供了链之间的隔离,这有助于限制攻击的影响范围。攻击撮合链只能使攻击者冻结当前保留在订单中的资金。攻击token链只允许攻击者窃取该链上的资金。未来会通过一些列措施来减轻这种攻击。一种解决方案是如何让矿工选择特定的链挖矿,从而使得51%的攻击被检测到并且通过持续增加hash算力来抵抗这种攻击。或者,可以使用不同的共识机制,例如权益证明(参考4.1节)。另一个问题是,无法确认一个区块是否处于最终不可逆状态,即该区块永久无法回滚。不过,我们认为现在的折衷方案能够有效地提高网络性能。去中心化的交易所为多链设计提供了一个独特的视角并且我们相信未来会解决这些问题,就好像随着时间的流逝,单链系统存在的问题被解决一样。

2.2 token链的行为

如3.1节所述,N Chainz采用余额模型存储所有token持有者拥有的余额,而不是采用像Bitcoin那样的UTXO模型。token链支持四种不同的交易:转账,冻结,订单和资金认领。转账交易允许在两个地址之间发起转账。冻结交易允许冻结address资金直到指定的块高度。订单交易允许以指定的汇率进行不同链的token交换。(参考2.4节)一旦一笔订单交易完成或者取消后,最终的资金就会存储在Unclaimed Funds池中。通过发起资金认领交易,用户可以将这些资金转移到自己的账户上。逻辑上来说,token资金是通过orderbook借给撮合链的,然后通过Unclaimed Funds池被回收到各自的token链上。如果想要销毁token,用户可以将token转到地址为0的地方。由于地址为64位,因此用户拥有地址为0的密钥的可能性可以忽略不计。

以下列出token链支持的交易的数据结构:

•订单交易

– ID:订单交易的唯一ID

–购买币种:要交换的其他币种(即不是发布此订单交易链上的币种)

–待售数量:当前链想要卖掉的token的数量

–待买数量:待买的其他链上token的数量。结合待售数量来定义订单价格。

–卖方地址:卖掉当前链上token的用户address

–签名:通过私钥签名以证明订单交易是由卖方地址发送的

•资金认领交易

– ID:资金认领交易的唯一ID

–地址:认领资金的地址

–金额:从Unclaimed Funds池中认领资金的数量

•转账交易

– ID:转账交易的唯一ID

–数量:转账数量

–发起者地址:发起转账的地址

–收钱人地址:收钱人的地址

–签名:通过私钥签名以证明转账是通过转账人地址发送的

•冻结交易

– ID:冻结交易的唯一ID

–数量:要冻结的token数量

–发起人地址:发起冻结token交易的发起者

–解冻区块:token可再次消费的区块高度

–签名:通过私钥签名以证明冻结是由发起人地址发送的

2.3 撮合链行为

撮合链充当主日志角色,对token链之间的交互事件进行全局排序。撮合链包含三种不同的交易类型:创建token交易,撮合订单交易和取消订单交易。所有token最初都是通过创建token交易在主链上创建的。通过orderbook寻找匹配项(参考2.4节)。最终,取消订单交易会退还订单中的资金并阻止该订单被撮合上。

撮合链支持的交易的数据结构如下:

•撮合交易

–撮合交易ID:撮合交易的唯一ID

–卖单token:卖方的token

–卖单ID:卖单ID

–卖方收益:以购买token形式给予卖方的金额

–买单token:买方的token

–买单ID:买方的ID

–买方损失:买方购买token花费的token

–转账金额:卖方花费的token和给予买方的token

–撮合商地址:找到匹配项的节点地址,该地址用来分红匹配上的订单的差价

•取消订单交易

–订单符号:取消订单的符号

–订单ID:要取消的订单ID

–签名:通过私钥签名以证明取消订单是订单创建者发送的

•创建token交易

–符号:新token的符号。作为token的唯一标识符

–总供应量:token的总供应量。该金额将在创建token时计入创建者地址

–小数:token的小数位数。这仅用于向人显示货币。

–创建者地址:创建者的地址。该地址需要在主链上拥有足够的token才能创建新链。并且在新链上该创建者的余额等于新链上的token发行总量。

–签名:通过私钥签名以证明订单是由创建者地址发送的

2.4 多链共识

通常,可以在每条链上独立达成共识。在单链系统中,区块始终可以回滚从而恢复到一个有效状态。但是,在我们的系统中,回滚链时必须检查两个不变量。首先,回滚订单时,这些订单不能再被撮合链上的“匹配项”引用。

其次,当在撮合链上回滚撮合交易和回滚取消订单交易时,Unclaimed Funds中存储的任何资金都不能变为负数(如果他们确实回滚相应的token链)。

在撮合订单时,只能允许被矿工验证过的订单交易出现在撮合交易里。否则,当撮合交易引用到同一个区块的订单时,会产生非法的状态。该区块将被网络拒绝,但可以由矿工生成。

3 共识状态

每个token链都需要商定一个共识状态。通过重放每条链中的所有交易,可以恢复这种状态。请注意,区块链日志的任何有效重放都会产生相同的共识状态。如果不能的话,那么存储的区块链将不是真实的日志,这将导致无法进行状态恢复和达成共识。

3.1 token链共识状态

与每个token关联的状态如下:

•余额:从地址到余额的映射。这与比特币的UTXO模型不同。这以牺牲轻量级SPV节点为代价实现了更高的性能和简化性,我们认为这是一个值得权衡的选择。

•Unclaimed Funds:Unclaimed Funds存储着从地址到token数量的映射。资金在完成匹配或取消订单后放置在此处,并且可以通过发起“资金认领”交易转移到用户余额中。

•使用过的的转账ID:一组使用过的转账ID。这样可以确保交易仅发生一次,并且不会被攻击者重放。

•被用过的冻结ID:一组被用过的冻结ID。这样可以确保交易仅发生一次,并且不会被攻击者重放。

•冻结资金:区块高度到冻结该高度的资金的映射。

•未完成订单:从订单ID到订单交易的映射。允许取消订单交易或匹配交易直接引用订单ID。当订单被撮合交易取消或使用后,该订单将被删除

•订单更新计数:订单ID到该订单发生变化的次数之间的映射。用来跟踪有多少还未撮合的订单。这是确保已匹配的订单不会回滚的必要信息(如2.4中所述)。从未完成订单中删除订单后,订单ID将从此映射中删除。

•已删除的订单:从订单ID到已删除的订单的映射。这样可以删除订单中的重复数据,还可以回滚撮合交易和取消订单交易。我们将在第7节中讨论如何不必将其存储在内存中,并且将来的实现应将其与相关块一起存储在磁盘上。

3.2撮合链共识状态

撮合链主要用于修改token链上的状态,同时也维护以下状态:

已创建的Tokens:key为token符号,value为关于该token的相关信息,比如总供给量,创建者地址以及精度。

使用过的匹配ID:一组使用过的匹配ID。这类数据不是必须的,不过可以通过这些数据在不处理撮合交易的情况下对数据进行去重,优化性能。

4 工作量证明

4.1 与其他共识算法的比较

为了简单起见,我们选择了工作量证明而不是权益证明。我们正在构建一个复杂的多链共识系统,不过针对原型开发,我们认为工作量证明更合适。

在工作量证明中,矿工解决了计算上的难题,以验证每个区块上的交易。因此,矿工成功创建区块的概率与他们拥有的计算能力成正比。比特币和以太坊目前基于工作量证明,这有助于提高此类系统的安全性。

相反,权益证明取决于可信赖的网络节点。由于利益关系,他们有动力去验证。因此,产生一个区块的概率与他们拥有的token总数成正比。我们研究了BFT风格的权益证明算法,认为工作量证明更易于实现,因此非常适合于初始原型。我们研究了很多权益证明算法,这些算法都生成部署简单。但是,我们发现其中很多权益证明算法存在重大的设计缺陷。例如,Tendermint似乎是一个很好的算法,但是区块仅由一小组提议者节点提议。这些节点是循环选择的,这意味着可以通过一次攻击一个节点来在整个网络上发起拒绝服务攻击。

我们认为当前的一些权益证明算法不靠谱,不过也期待诸如Ouroborus Genesis和Algorand这样的新型权益证明算法,它们不会遭受与这些系统相同的简单DOS攻击。我们认为,我们每种token一个区块链的模型可能非常适合于权益证明或混合的工作量证明和权益证明解决方案。

4.2矿工

新交易将添加到未验证的交易池中。每个矿工选择一个随机的token链进行挖矿。然后,对于该token,矿工尝试挖掘当前池中的交易以及新交易。矿工将获得每笔交易固定百分比的奖励。这些激励措施最终将需要由社区决定。

我们通过使交易池中的所有交易唯一,并在挖掘之前通过共识状态对每个交易进行验证来确保交易是有效的。

目前,我们设置了一个固定挖矿难度。我们研究了调整难度的方法-例如,比特币调整其难度,使得大约每10分钟产生一次区块。但是,我们决定在最初的原型制作过程中保持固定难度值。

每个链条分别达成共识。尽管节点需要跟踪所有链,但它们一次只在一个链上出块。遵循最长链原则。如果矿工的链条较短,他们将从网络对等节点那里获得最新版本的区块。

4.3 撮合商

撮合商是矿工的子集,根据orderbook上的订单提交撮合交易。任何节点都可以选择查找匹配项,但是我们希望只有一小部分子集会参与,并通过匹配项之间的差价来激励它们。这实际上是设计使然,因为不需要在每个节点消耗CPU和内存来寻找订单之间的匹配。通过将这种计算限制为高性能节点,我们实际上减少计算浪费并提高了吞吐。这也是拥有一个独立撮合链的另一个重大优势,可以尽可能将多个匹配项放置到一个区块中。所有节点仍必须验证所有的匹配项,因此不必担心有51%攻击。

5 订单匹配

作为交易所,N Chainz的主要功能是允许不同链上的token进行交易。并且所有token交易数据全部存储在链上。

5.1订单

像任何其他交易所一样,N Chainz允许用户通过限价订单交换token。在大多数交易中,限价单指定用户希望以最多或至少一定价格(以美元等基础货币)买卖一定数量的资产(如比特币)。但是,对于N Chainz,资产相对于基础货币的概念是模棱两可的,因为每个token都可以交换为任何其他token。因此,N Chainz订单指定用户希望购买一定数量的一个token(购买数量)以换取最多一定数量的另一token(出售量)。因此,所有订单都是一个token的买入订单和另一个token的卖出订单。

N Chainz中的限价单为取消前有效(GTC),这意味着它们永远不会过期。如果用户想取消其订单,则可以通过取消订单交易来取消。订单交易和取消订单交易都存储在其所出售token的链上。

5.2 orderbook

orderbook是一种数据结构,主要由交易所使用,用于将资产的买方与资产的卖方进行匹配,其中买方和卖方使用相同的基础货币。一个典型的交易所具有报价侧(包含希望购买资产的订单)和基准侧(包含希望出售资产的订单)。在N Chainz中,每个货币对都有一个orderbook,

要注意,orderbook是节点保留在内存中的数据结构,以促进匹配,而不是存储在区块链上。在此orderbook的上下文中,可以将订单分类为:买家订单以及卖家订单。

5.3 匹配

当买家价格大于卖家价格,就可以在orderbook上撮合对应的买单与卖单。每一个订单撮合交易都会涉及到一定数量的金额转移,包括从卖方转给买方,买方转给卖方。买方和卖方订单可以全部撮合完,也有可能只撮合一部分。

如果买家出价恰好等于卖家出价,则卖方收益等于买方损失,否则的话,卖方收益小于买方损失,差价用于奖励矿工。

5.4撮合引擎

撮合引擎是系统组件,用于跟踪orderbook并撮合订单。每个orderbook包含两个堆,用最大堆来跟踪买家订单,用最小堆来跟踪卖家订单。每当系统达到一个稳定状态(当前没有回滚任何区块)时,撮合引擎都会检查匹配项。撮合商引擎会从两个堆依赖提取数据进行撮合。

6 网络

像任何其他区块链系统一样,N Chainz分布在对等网络中的各个节点上。每个N Chainz节点负责存储区块链的副本,维护共识状态的副本以及响应网络RPC调用。另外,N Chainz节点可以选择挖掘新块并撮合订单。

6.1 RPC消息

N Chainz节点通过RPC调用交换消息。所使用的消息类似于比特币的消息,但经过修改以适应我们的网络设计。

6.1.1版本

建立连接时,网络对等方使用VERSION作为握手。当一个节点听到一个新的对等节点时,它会向它发送一个VERSION消息,其中包括正在运行的N Chainz协议的版本。当节点收到VERSION消息时,它确保它正在运行相同版本的N Chainz,如果是,则以其自己的VERSION消息进行响应。如果每个节点尚未成功交换此VERSION握手,则它们拒绝来自对等方的RPC调用,以确保网络中的所有节点都遵循相同的协议。

6.1.2地址

ADDR是指网络节点地址。节点使用ADDR(即地址)与其他节点共享已知对等方的列表。每当N Chainz节点连接到新对等节点时,它都会向其现有对等方广播ADDR以通知他们该对等方。当节点收到ADDR消息时,它将尝试使用VERSION消息连接到所有新对等方。尽管此设计使退化的网络拓扑难以出现,但随着此系统的扩展,它将给网络带来过多的负载。为了解决这个问题,我们计划引入一个节点系统,以限制与其通信的其他节点的数量。

6.1.3 TX

TX是指交易,交易会被转发到网络中的节点并且最终应该被打包到一个区块中。TX可以由客户端转发,也可以由网络节点转发。当N Chainz网络中的用户想要组建一笔交易,他会用客户端将该交易转发给网络中的节点。当网络中的节点收到一个交易时,该节点会依据当前账本状态验证交易是否合法。验证过程取决于交易类型,例如核查用户是否有足够的余额进行转账交易,或者一个订单是否被一个撮合交易引用。如果新的交易是合法的,节点会将该交易转发给它的邻居节点。如果当前节点是矿工节点,它会将交易加到已验证交易池以待被打包到区块中。

6.1.4 INV

INV即存储列表,用于存放某条链的区块hash,N Chainz节点会定期将存储列表中的数据广播给所有已知的对等节点,我们计划只提供最近的区块hash,按需提供较老的区块hash。当节点收到一个INV请求时,它会使用链协调机制来比对本地的INV与收到的INV。

6.1.5 GETBLOCK

给定区块hash和链名,节点可使用GETBLOCK接口获取区块,并且在节点账本同步的时候也会用到GETBLOCK。当节点收到GETBLOCK请求时,会查找本地账本是否包含特定区块,如果有的话,则返回该区块数据;如果没有,则返回错误。

6.1.6客户端RPC消息

N Chainz节点之间还可以响应其他一些请求用于获取节点的当前状态。GETBALANCE请求用于查询用户的余额,GETBOOK请求用于查询orderbook,DUMPCHAINS用于dump链上最近区块的相关数据。我们的Web界面目前支持这些功能,我们发现这些信息是实用的。

6.2链上账本同步

当节点收到一个INV请求时,会将本地的INV与接收到的INV进行对比,通常这两个INV会有差异。为了达成共识状态,本地节点需要判断哪个账本是最新的,哪个账本是最长链上的账本。如果本地节点认为网络中其他节点账本是最长链上的,本地节点会将本地账本回滚到公共区块并Walk到网络中最长链对应的区块。因为同一个区块链网络中所有节点具有相同的创世区块,因此回滚+Walk操作是可行的。在操作过程中使用GETBLOCK获取缺失的区块。同时在确认区块时,需要验证区块的合法性,一旦发现非法交易,则终止账本同步过程。

6.3 引导

新的N Chainz节点想要加入N Chainz网络的话,需要知道至少一个现有节点的网络地址。每个节点保留一个种子节点列表,方便接入对应的网络。

7命令行和Web界面

所有块。我们开发了一个命令行界面,帮助用户管理账户,创建交易以及启动节点。管理账户:用户可以创建钱包,获取某个链某个地址的余额,打印所有地址。创建交易:用户可以在不同token之间设置限价订单、转账、取消订单、认领资金以及创建新token。用户也可以在特定主机和端口上启动挖矿节点,打印某个链上的所有区块。

我们还开发了一个Web界面,可直观显示订单匹配情况,并实时显示时间窗口为3分钟的价格历史记录。

N Chainz:一种去中心化、高性能加密货币交易所_第3张图片

图3:命令行界面帮助菜单的屏幕截图。

8 结论

我们计划为最初的原型增加更多功能。具体来说,我们将实现token的冻结和销毁,用本地token直接交易,挖矿难度动态调整,产出交易执行报告。

同时,我们也计划去调研POS算法,提高系统的性能。

最后,我们还打算做一些优化工作:例如,改进对等网络,如何存储已经删除的订单等。(目前,我们是将已经删除的订单存储在内存中,而不是写到与块关联的磁盘中。)

致谢

同时,感谢Ivan Kuznetsov的区块链教学课程,该课程帮助我们入门区块链。

代码

中找到我们的代码库链接为:https://github.com/rsenapps/nchainz

N Chainz:一种去中心化、高性能加密货币交易所_第4张图片

图4:Web界面截图。第一张图为显示匹配的订单。第二张图为显示最近3分钟的价格历史记录。

你可能感兴趣的:(区块链)