原文标题:《波卡底层技术分析:共享安全与平行链卡槽》
原文作者:陈锡亮(Acala Network 联合创始人兼 CTO)
原文来源:BeWater Community
原文编辑:钰承
波卡是一个异构的区块链。比特币作为第一代区块链来说,主要的功能是转账。以太坊作为第二代区块链拥有的智能合约功能,用户可以上传智能合约,然后发布自己的应用。但以太坊目前到了一个瓶颈阶段:所有人包括以太坊官方自己都认为,目前以太坊不足以承担未来的职责,所以 Gavin Wood 离开了以太坊创建了波卡,来打造他认为最适合有长远发展的 web 3.0 技术。
区块链目前最大的瓶颈之一是性能限制,解决性能瓶颈一般有几种方式:横向发展跟纵向发展。
纵向发展就是分层,横向发展就是分片。波卡使用分片的技术。以太坊 2.0 比较类似,但以太坊 2.0 使用的是同构分片,波卡使用的是异构分片。你可以用波卡来实现以太坊 2.0,只要保证每一个分片都是一个智能合约片就行。所以说异构分片在从技术架构上来说明显优于同构分片,因为只要能实现异构分片的技术,就可以非常简单的实现同构分片的技术。
这个图是波卡的一个非常简单的架构,分别有几种角色:中间的 Relay Chain 是波卡中继链,然后每个中继链会连接多个 Parachain,每个 Parachain 就是平行链,然后每个平行链都是自己的一条链,成为自己的 layer 1,所以说波卡连接所有平行链,有人说波卡的是一个 layer 0 的协议。
每一个平行链的安全是由 Validators 验证人,来维护整个波卡网络的安全性。然后同时这些 Validators 也验证了这个平行的安全性,每个平行链还有一些 Collators 收集人,这些我会在之后再详细介绍。那波卡生态作为一个跨链的核心,自然不能是一个很自闭的生态,我们希望是可以连接到除了波卡生态,还有以太坊,其他新兴生态,打造一个互联互通的一个区块链 3.0 的未来。所以桥也是一个非常重要的部分在这个生态之中。
「桥」实际上是一个普通的平行链,但是它的目的就是为了能跨其他的链。所以通过桥可以使波卡生态连接到其他的生态,包括比特币、以太坊等。这些跨链桥有一些已经实现,有一些在实现中,所以说这样就可以打造一个完全开放式的,可以互通整个区块链网络的生态。
延伸阅读:
https://wiki.polkadot.network/docs/getting-started
https://research.web3.foundation/en/latest/index.html
https://w3f.github.io/parachain-implementers-guide/
第一个是去中心化。波卡希望支持至少 1000 个验证人节点,算是一个非常去中心化的网络。
如果全世界这么多人竞争二十一个节点,成为一个节点的成本将会非常的高,但如果你竞争前 1000 个节点,这个成本会相对低非常多。当然如何以去中心化的方式,选前 1000 个节点也相对复杂。
很多 POS 使用的方法,简单来说是每一个持币人都可以作为提名人,提名人可以选举验证人,但问题是提名人只能选举一个验证人,而提名人只有在他选举的验证人被选入之后,他才会有收益,导致的结果只有 21 个验证人的网络,第 21 个人和第 22 个验证人之间的票数差距是非常巨大的。所以说导致的结果,是既得利者非常容易在这个圈子之中,外来者很难打破平衡。那这个实际上对去中心化来说不是理想的状态。
波卡实现了 NPoS 算法:每一个验证人可以选举最多 24 个验证人,只要 24 个之中任意一个被选上了,你就会得到 10 staking 的收益。这样大家会有动力选他认为更优秀的验证人,而不是选他一定会选上的人。这不会产生非常高的壁垒,使得新的验证人加入会比较容易。
所以说这个选举算法就会变得比较复杂。因为一个人有 24 票,这个票数是动态分配的,那么全局算法就会比较复杂。使用了 Sequential Phragmen 算法,验证人的选举是非常去中心化的,所以说这是波卡去中心化的其中之一。
延伸阅读:
https://wiki.polkadot.network/docs/learn-phragmen
https://research.web3.foundation/en/latest/polkadot/NPoS/index.html
作为一个区块链网络,安全自然是非常重要的。波卡有相关的各种方式保证它是安全的。我先侧重的说一下 BABE 这个出块的选举算法。因为波卡可以支持上千个验证人,但是每一个区块不可能让这一千个验证人同时出一个区块,所以说如何选下一个出块人也是一个问题。
这个做法目前是普遍有两种方式,最简单的方式就是使用按顺序来轮流来大家排个队,一人出一块就完了,这个是可行的,但是他会有一些问题,比如说谁是下一个出块人是可预测的,就会使得一些攻击就会比较容易实现,这个是比较危险的。
第二种方式就是使用 VRF (Verifiable Random Function) 的方式。这可以使出块人的选举方式有一定随机性,你没有办法预测到下一个出块人是谁。好处就是验证人合伙作恶的可能性大大降低了,因为他并不知道什么时候他自己会被选上,他也不知道他被选上之后接下来几个验证的都是谁,再加上一共有上千个验证者,要勾结几个人做成本就会大大的增加。
VRF 有一个 slot,每 6 秒钟是一个出块的区间,这个时候大家每一个验证人都会知道自己手上有一根签,这个签单只有他自己能看到,每 6 秒钟抽一次签,如果抽中了他就可以进行出拥有出块的权利。同时出块的时候可以发布一个证明,证明他确实抽中这一根签。
当然这种随机抽签的话有一个小小的问题,你没办法保证只有一个人选中,你也没有办法保证一定会有人选中。所以就有可能会出现一个 slot 里面有多个 validator 或者说没有 validator。这个 BABE 也做了一些的处理,多个的 validator 的话相对容易来说会导致产生一个分叉,但是最终来说的话只会有一个分叉成为合法分叉。
如果说没有任何选中的话,他会使用回排序的方式,说每一个 slot 会有一个 primary 做主要的这个出块者,还有一个 secondary 一个次要的出块者。primary 就是使用 VRF 来选的,如果说没有人选中或者说选中的那个人不在线,或者说他因为某种原因他不出来声明说他选中,不进行出块。那么就会有一个替补,这个替补可以出来进行一个出块的动作。这使得在验证出块方面达到一个比较好的随机性,同时使一些外来者的攻击更加困难:比如你可以快速的预测到下一个出块人的话,那你可以针对这个人的网络,服务器,你可以作为一个 DOS 的攻击,发一堆流量,把这个服务器给打垮掉,使得网络瘫痪。
但如果说你不知道谁是下一个,那你必须得同时攻击这上千个验证人,那这个攻击成本就直接翻了一千倍,所以说也使得网络在更加的安全。BABE 也不是说一个完美的算法,波卡正在做这个 SASSFRAS 算法,就可以使得每一个 slot 之间只会有一个,并且一定只有一个的这个出块人。就不会产生多个人同时抽到一签,或者说同时没有人抽到一签的情况发生。这个算法在现在应该是在一个审计的阶段。
延伸阅读:
https://wiki.polkadot.network/docs/learn-consensus#block-production-babe
https://research.web3.foundation/en/latest/polkadot/block-production/Babe.html
然后下一个的话作为一个新世代的区块链网络的话,那我们势必是要保证这个网络是一个高效的。那这个同样,我会我只是先说其中比较重要的一点就是 GRANDPA 这个算法。BABE 是选择这个谁是出块人,谁有出块的权利。GRANDPA 则是去做一个这个最终确认的这么一个过程。因为 Babe 来说的话是还是有导致这个 fork 的可能性的。
如果在产生 fork 的情况下,那么谁才是真正的这个被敲定到一个区块,这个就是由 GRANDPA 进行这个确认。那 GRANDPA 和传统的这个 PBFT 这个算法可以说是一个扩展,它原理上是几乎一模一样的,都是需要有超过 2/3 的这个诚实节点才能防止拜占庭攻击。
但是 GRANDPA 它和传统的这个算法来说有一个最大的优势,就是说它可以一次性快速的 finalize 大量的区块。如果说作为一个传统的这个比如说 pbft 这个算法,他一次性只能敲定一个区块,这就是直接限制了它的效率。但是 GRANDPA 理论上,它一次性的可以敲定上百上千个区块。
所以说它使得这个在发生比如说网络故障或者说有一部分节点掉线的情况下,如果说是传统的这个 Tendermint 的算法,它这个就会直接导致网络的停滞。但是如果使用 GRANDPA 的话,那就没有任何关系,只是说有一段时这网络还是可以正常的往前走,正常的出块。但是它的 finalize 会停下来,但是一旦网络恢复正常,一旦有足够的节点上线,它可以在几秒钟之内就把这个最终敲定的区块的直接跟上来。
延伸阅读:
https://wiki.polkadot.network/docs/learn-consensus#finality-gadget-grandpa
https://research.web3.foundation/en/latest/polkadot/finality.html
在波卡上面有几千个提名人,几千个 validator。所以说你要在这么多人之间要选这个最优秀的和 200 个或者 300 个验证人的话,不管这个算法是怎么被优化,它的计算量都会比较庞大。大家应该知道这个链上的计算是非常昂贵的,因为这个需要每一个节点都进行运算,而且它是有时间有限制的。所以说在链上做这个运算就不是非常的适合。
波卡的网络是 6 秒钟一个块。6 秒钟一般是分为三个部分,其中 2 秒钟是出块的时间,2 秒钟是网络传输的时间,2 秒钟是引入上一个区块的时间。所以说一共是 6 秒钟,但是其实只有 2 秒钟时间在进行出块。所以说这直接限制了这个选举算法必须在 2 秒钟之内执行完成。这个在网络人数少的时候是可行的,但是在人数多的时候就会变成一个非常大的限制。所以说波卡用 off-chain-worker 工作机这个技术来解决这个问题。这也是一个比较全新的技术,据我所知在其他网络之中应该是没有的。
然后简单来说这个 off-chain-worker 就是可以在网络可以使一段代码在链下进行执行。Phragmen 这个算法它会把节点在链下进行计算,寻找最优秀的提名方案。然后进行计算之后然后再将最优秀的这个方案传到链上。因为验证这个方案是一个比较快速的过程。然后这样就可以以一个性能上比较适合的方式进行一个选举,把大量的计算过程在链下执行,在链上只会选举分数足够优秀的方案。这样就可以突破链上两秒钟执行的时间限制。
Off-chain-worker 除此之外还可以做很多的其他事情,比如说目前也是做到用来做这个发送验证的心跳也是使用 off-chain-worker 来执行。然后这个 off-chain-worker 有非常强大的很多 API,他甚至可以发送 HTTP 的 request。比如说最简单的案例,可以与 coinmarket cap 等等的这些价格网站直接询问价格,然后将这些价格信息发到链上,可以做很多这个传统区块链架构是不可能做到的事情。所以这个也是一个和其他的区块链开发框架来说一个比较有独特优势的地方。
延伸阅读:
https://docs.substrate.io/v3/concepts/off-chain-features/
https://wiki.polkadot.network/docs/learn-phragmen#off-chain-phragmén
波卡的这个共识算法实际上是一个混合的算法。他将这个出块和 finalize 做了一个区分,做了一个拆分。因为 BABE 的话是直接只要这个你随机抽中的这个节点在线,或者说他的备选节点在线,那么他就可以进行一个出块。只要有一个节点在线,就算其他节点全部死掉了,都不会影响网络正常的出块。那所以说这个大大提高了网络的可用性。
当然了为了这个安全性的话,我们还是需要 finalize 的。所以 finalize 还是需要要有超过 2/3 的诚实节点在线。但是因为这两个是区分开的,所以说在这个如果说网络发生了问题,BABE 进行自己出块,然后在网络恢复之后,可以在几秒钟之内重新再把这个 finalize 这个区块跟上来,所以这个混合公司算法得大大提高了这个网络的可用性和安全性。
然后接下一个说这个更多的是平行链扩展的部分,使用了这个收集人验证人的这个架构。我刚刚已经简单的提到了,说波卡自己是一个中继链,然后中期链又有他自己的 validator 然后这个每一个然后这些 validator 会负责验证一些这个平行链的安全,然后每一个平行链都有自己的 collator 那 collator 就是收集人,他负责这个平行链的出块,但是他并不负责这个安全性,所有的安全性能都是由这个波卡的验证人来进行执行的。
所以说导致的结果是大家不需要相信 collator。这些 collator 本质上没有任何作恶的能力。这使得对一个平行链来说,相对波卡来说,collator 有几个就行了,反正这些 collator 是没有能力作恶的。这使得平行链的安全性能得到一个大大的提高,同时的大大的降低了运行一个平行链的成本。因为你只需要拥有几个 collator 就可以了。
延伸阅读:
https://wiki.polkadot.network/docs/learn-collator
(1)共享安全性
所以说这个共享安全的最大优势就是使得所有的平行链的可以共享到波卡主链的网络的安全性。这个是一个非常重要的一点。因为作为一个 POS 的网络的话,你想拥有一个很好的安全性能是非常困难的,你必须拥有一个足够的这个网络的 Token 的市值,你必须拥有一个足够分散的这个节点。所以说这个都不管是在运营方面和这个资金方面都是有一个非常高的门槛的。波卡的使用共享安全的这个技术,就可以使得这个平行链直接使用到这个波卡的安全性。
所以说这个是一个非常必要的方式,否则导致的结果是不同每一个网络都会势必产生一个这个安全性上的竞争。最简单的例子就是各种比特币的分叉,他们每一个矿工的之间这个小型的网络,它的 hash rate 是非常低的,然后就非常容易被双花攻击。然后同时小型的 POS 网络,因为 Token 的市值太低,所以说也非常容易被收购到足够的 Token,然后进行这个 1/3 的攻击等等。
但是如果说这个平行链的网络是基于这个波卡安全性的话的,那么攻击任意一个平行链的成本都是与攻击这个波卡自己的成本是一样的。这会达到一个非常高的成本。然后但是这个只是共享这个共享安全的这个重点之一。
那共享安全其实还有达到另外一个效果,也是非常重要的,实际上是为了这个跨链技术的服务。因为跨越技术其中有一点是非常困难的,假如你有 100 个区块链互相自己可以跨链沟通,这个币在这 100 个链子之间是可以互相转来转去的。那么你这个就会有一个问题,如果说这 100 个链最终有一条链被攻击了,然后他被恶意操控了。那么这条链是不是有可能就可以无限增发其他链的货币,然后通过跨链的方式把这个货币转到其他链上,然后导致其他的这些所有与这条被攻击的链相连的链都会受到这个攻击。
所以说使用共享安全的话,就可以保证这个网络之中没有短板。在做这个跨链技术的开发之后,我们当然还是要考虑很多其他技术细节。但是有一个事情不需要考虑就是这条链的这个消息否对方这条链的是否注足够安全。而且因为是使用这个中继链和平行链的架构,所有的跨链消息都是会被这个中继链的验证人进行验证的,然后同时会得到这个中继链的一个保证。
所以说导致的另外一个优势比如说链 A 给链 B 发一条消息。链 B 收到之后,这条消息实际上是经过中继链保证的,中继链确确实实验证过这条链是链 A 发送过来的,这样子的练 B 就可以直接相信这条消息是因为通过共享安全性。所以说这个很多消息来源的验证的方式就完全是不需要考虑的。所以说这个也使得跨链的技术实现来说会容易得非常多,所以也是波卡的跨链的优势之一,可以使得链与平行链之间暂时得到一个非常高效的一个跨链的消息的传递。
(2)治理问题
然后那这个只能保证这个链与链之间的消息的传输的的合法性的验证。但是有一个问题并不能解决,治理的问题。理论上来说,所有链在基础安全性都是一致的情况下,还有一种攻击方式就是治理攻击。
你可以如果说有一条平行链,他的自己 Token 价钱足够便宜,那么攻击者可以大量的收购这个平行链 Token,使得他控制这条链的治理权,然后甚至就可以做一些操作,比如说同样大量的恶意增发其他链的币 或者说篡改一些消息。那这个解决方法,就是其针对攻击问题,波卡也是提供了一个解决方式。
大致来说的话,就是举个例子,大家的手机电脑之间都有一个可信硬件,叫做 TEE 的一个芯片,然后包括在 iPhone 上或者 Mac 上,甚至在所有的大部分的新的 CPU 上面都有这么一个可信执行区域,然后在这里面执行的所有东西都是会被认为是可信的。比如说你 iPhone 上面用指纹解锁,用 facetime 解锁的话,所有的这个指纹的信息都是在这个可信区域里面执行的。这个认为是不可以被恶意攻击操纵的。这个使得很多安全性上面的东西的开发就会非常容易,因为你只要在 TEE 里面执行,你就会认为它是安全的。
那这个时候也是达到一个类似的效果,平行链如果说选择使用 SPREE 这个组件的话,他并没有能力修改这个组件的代码的能力,因为这个组件是由这个中继链来进行维护的,所以说是可以把一些非常重要的比较敏感的一些代码,比如说这个 Token 的转账、增发销毁逻辑等等放在这个框架里面。
那么这样的话其他平行链就可以相信相对应的 Token 的转账的操作是会被正确执行的。其他的平行链就算是进行恶意攻击,他也没有能力作为一个恶意的增发等等。因为这部分的这个逻辑并不会被其他平行链所操纵,所以这个同样也会解决了非常多的一些信任上的问题,你不需要信任对方,因为对方没有作恶的能力。所以这个也是波卡技术非常优势的一个问题。也是目前来说我没有看到其他的技术有解决这个方式的方案。
当然这个理念是非常先进的。先进到这个目前来说一行代码都没写出来。所以说这个在实际使用这个东西的话,我们可能还需要等待一段的时间才能真正用上这个功能当然了,大家有兴趣的话,也欢迎参与到这个 SPREE 的一些技术细节的讨论和探讨。这个也是会在波卡平行链上线之后的这个开发的一个非常大的侧重点。
延伸阅读:
https://wiki.polkadot.network/docs/learn-security#shared-security
https://wiki.polkadot.network/docs/learn-crosschain
https://wiki.polkadot.network/docs/learn-spree
那接下来我说一下这个关于卡槽的一些东西。当然我已经说到了波卡的这个价格,我们有中继链还有平行链。然后实际上还有一个平行线程这么一个概念。当然了这个实际上就是非常简单的,平行链就其实像一个多核的电脑,然后每一个链就是每个应用占用一个核,然后这个核是由它独有的,然后平行线程就是一个 thread 然后他等于多个线程之间共享几个合核心。然后使得有一些对于这个比如说交易量比较少的应用它不需要永远在线,它就可以和其他的一些同样的线程共用一个核心,这个就使得这个网络能达到一个更高效的一个分配。
当然了平行线程目前也是属于一个开发阶段,目前还没有上线。但是因为它的核心功能是和平行链是一致的。所以说希望在这个平行链上线之后的不久的未来,我们就可以看到平行线程。
然后这边又说到了这个验证人的这个分配机制。在波卡的这个白皮书来说,他会说波卡会有 100 个卡槽。所以说很多人会有这个问题,为什么是 100 个卡槽?100 卡槽用完了怎么办?不够用怎么办?然后不够用的这个问题,就是做一个二级的 relay 所以说我们有波卡这个链波卡会连到 100 个平行链,然后这 100 个平均链每个自己也是一个中继链,100 个链又连 100 个链,那我们就有 1 万个链了,1 万个链 100 个不够,1 万个总该够了。所以这个是波卡解决方案。这 100 这个数字怎么来呢?波卡的一开始的设计是它支持 1000 个验证人,然后他们又会去分配,然后每 10 个验证人,然后负责验证一个平行链。那我们 1000 个验证人 10 个平行链,那我们就有了 100 这个数字。
当然因为这个验证人的上限并不是 1000 个。这上限具体的多少实际上大家都不知道,所以 Kusama 会在接下来一年之内会不断的增加这个验证和数量,在实际的网络之中来探索这个这个验证的数量的上限。那这样我们就会知道波卡实际上最多可以支持多少验证人和多少个平行链。然后同时这个 10 也是当初设定的一个数字。
现在每个平行链实际上只分配了 5 个验证人。这个也是 Web3 他们之后一些更多的研究,他们认为有五个验证人可以做到足够安全的了。
延伸阅读:
https://research.web3.foundation/en/latest/polkadot/networking/1-parachains.html
当然这个肯定会有人问,要是这五个验证人都是一伙的作恶怎么办?所以说波卡的这个验证并不是仅仅简单单的就相信这五个验证人。当然首先第一点就是因为从 1000 个里面选 5 个,然后这 5 个在一起作恶的可能性是在因为作为 POS 网络的话,一个最基本的这个设想是至少有 2/3 的节点是诚实的,然后在 1/3 的节点是作恶节点之中,然后再随机有 5 个分配到一个你想要攻击的这个平行链,他们认为这个机率是足够低的,所以说这是足够安全的。
然后就算这种情况发生了,这只是一个第一步的验证。实际上还有一个第二步的验证。
波卡刚刚我说过了出块和这个最终的 finalize 是分开的。所以这个和平行链的这个机制实际上也是一致的。这 5 个验证的人会验证一个平行链的节点,然后将其打包放在这个平行链的这个区块,将平行链区块头打包,然后放到这个波卡中继链的区块之中。然后这个会波卡的区块会进行一个出块,然后这个就会被认为是确认了。
确认是不够的,我们一般情况下要有敲定的过程,这个就会涉及到了波卡的这第二个机制。波卡在 GRANDPA 验证之中,他们又会进行作为一个第二步的验证。然后来再次验证这个这五个人打包了这个平行的链的区块是否是合法的。所以说这就使得这五个这个作恶的几率。就算这五个人作恶,他们可以在波卡的区块里面打包这个非法的平行链的区块。这个等于就创建了非法的中继链区块,它有可能会被确认,但是它并永远不会被 finalize。
延伸阅读:
https://research.web3.foundation/en/latest/polkadot/networking/3-avail-valid.html
对于这个传统的这种英式拍卖的话来说,就是大家出价,然后最终出价高者得。这个在区块链上进行事情也是有非常多的问题。首先你这个拍卖势必要有一个时效性,你不能让大家这个拍卖永远的拖下去,这样的话很容易比如说恶意攻击,大家合谋,每次就多出一块钱,大家都不想多拍,那每次加一块钱,那真的不知道拍到猴年马月去了。所以说波卡了是使用了蜡烛拍卖,这个蜡烛是拍卖。简单来说这个拍卖分两个周期,第一个是一个正常的出价周期,第二个是一个随机熄灭的周期,然后最终拍卖结束之后,他会使用到 VRF 这边提供的这一个随机性数字,然后利用这个数字随机的选出一个区块,由这个区块里面价格最高者获得胜利。
然后这个也是为什么这个在如果说你有关注波卡拍卖的话,你会发现并不是拍卖一结束这个结果就出来的,一般要等两到四个小时,这也是等足够安全的随机数出来,然后才能做一个这个确认拍卖结果的这个区块。
然后这个蜡烛开发为什么要这么设计呢?他们所需这个主要解决的问题就是说一个是保证这个拍卖可以在游戏在确定的时间之内完成不可能永远被拖下去。第二个就是说避免大家最后一秒出价,因为如果说是一个有时效的正常拍卖方式的话,那么最优策略势必是在最后一秒钟再出价。
所以说是这个蜡烛拍卖机制的,会鼓励大家就在随机熄灭之前,越早把那个筹码交出来越好。因为你交的就算你是在这个拉住新妹周期的最后周期开始之前最后一秒钟出价,那也无所谓。反正其他人之后看到你出价再加就是了呗。因为在实际期免周期的开始之前加价是没有那种太多影响。但是如果你选择在熄灭周期的最后一秒钟出价,那么出的这个价有非常大的几率是无效的。所以说这个也使得拍卖的参与策略,从某种意义上来说就更加简单了,反正你就一开始 all in 就行了。然后所以这个就是蜡烛拍卖。
延伸阅读:
https://research.web3.foundation/en/latest/polkadot/economics.html
https://wiki.polkadot.network/docs/learn-staking#inflation
然后这边也再顺便说一下波卡的 Token 经济的设计。因为波卡这个币每一个区块链项目它的币基本上都应该是有一定的用处的。波卡他认为自己的币是一个工具式的币而不是一个货币这么的概念。
所以说在早期的这个波卡经济模型的设计有一个非常激进的想法,就是说这个增发率年化甚至达到百分之五十之多。那导致的结果是如果说你不参与 staking 那么你这个资产大幅度的贬值会。进而以一种类似强迫的方式使得大家也参与到这个网络之中。当然这玩意就是反正大家都可以觉得太激进了。然后所以说最终没有使用到,所以说现在使用一个相对合理的 10% 的增发率,大家对波卡的经济头设计有兴趣的话,同样也可以看这个链接里面有一些非常多的一些用信息。
分享了也有一个多小时了,所以说我今天的分享到这里了,接下来是一个自由问答的环节,然后大家有问题的话现在可以提。
延伸阅读:
https://wiki.polkadot.network/docs/learn-auction
原文链接
欢迎加入律动 BlockBeats 官方社群:
Telegram 订阅群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方账号:https://twitter.com/BlockBeatsAsia