查看原文
其他

技术 | Web3应用程序架构

阿法兔 阿法兔研究笔记 2022-04-18

本号上两篇文章,主要是从概念和生态上来描述Web3, 有助于对Web3有初步的宏观认识,阅读请点击:


编译&发布本文的主要目的是,让大家能从技术架构对Web3的DApps建立简单的认识,建议有程序开发背景的朋友阅读,当然如果您不是工程背景,愿意了解其中的原理,也可以一看。文末附赠大家的礼物:web3.js Documentation


注: 本着客观独立的出发点,本号不推销任何意义上的商业产品,不提供任何投资建议,不接任何PR需求。本文不构成任何投资上的建议。


*本号文章大多属于为爱发电,供参考和学习使用,欢迎大家转发。

作者 |Preethi Kasireddy

编译 |阿法兔

序言


*本文5000字左右,阅读时间大概15-20分钟

Web 3.0的应用程序(DApps)的架构与Web 2.0时代的App完全不同。以博客网站Medium(类似博客园)为例,用户可以在Medium网站发布文章,与其他用户互动。我们每天都在接触类似的Web 2.0应用,用起来似乎很简单,但要实现这些功能(发布文章、与用户交互等功能)等,还是有很多准备工作需要网站完成。
具体需要做哪些工作呢?
第一,网站必须具备一个可以存储基本数据的空间,储存用户、帖子、标签、评论、点赞等,数据库需要不断更新。
第二,后端代码(用Node.js、Java或Python等语言编写)需要对Medium网站的业务逻辑进行清晰的定义。例如,当某个新用户注册、发布新博客或在别人的博客上发表评论时,网站会有什么样的变化?
第三,前端代码(通常用JavaScript、HTML和CSS编写)必须定义Medium的用户界面逻辑。例如,网站是什么样子的,当用户与页面上的每个元素(例如按钮、状态栏、小图标等)互动时,会发生什么?
组合在一起,当我们在Medium上写一篇博文时,会与它的前端互动,与后端对话(后端还要和数据库对话)。这些代码都托管在集中式服务器上,通过互联网浏览器发送给用户。通俗来说,大家今天使用的大多数Web 2.0 App的工作方式就是如此。

但是,变化正在发生。


区块链技术为Web 3.0应用开启了一个新的方向,为了加深理解,这篇文章将着重分析基于以太坊的Web3的DApps架构。


Web 3.0到底有何不同?


与Web 2.0应用不同,Web 3.0消除了中间商(管理中心)。无需数据库集中存储应App的状态( State),也不需要集中的网络服务器来存放后端的逻辑。


相反,Web3可以利用区块链,在互联网上的去中心化的状态机上(由匿名节点维护)构建应用程序。


通过 "状态机(state machine)",这里是指维护给定的程序状态和该机器上允许的未来状态的机器。区块链是状态机,它被实例化为一些创世的状态,并有非常严格的规则(即共识)来定义该状态如何转换。


科普:什么是状态机?


状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作,完成特定操作的控制中心。状态机分为摩尔(Moore)型状态机和米莉(Mealy)型状态机。 


状态机就是状态转移图。举个最简单的例子,人有三个状态:健康,感冒,康复中。触发的条件有淋雨(t1),吃药(t2),打针(t3),休息(t4)。所以状态机就是健康-(t4)->健康;健康-(t1)->感冒;感冒-(t3)->健康;感冒-(t2)->康复中;康复中-(t4)->健康,等等。就是这样状态在不同的条件下跳转到自己或不同状态的图。


没有存在的实体控制这个去中心化的状态机,状态机是由网络中的每个人共同维护的。

那么后端服务器呢?与Web2.0后端被控制的方式不同,在Web 3.0生态中,我们可以编写智能合约,定义应用程序的逻辑,将应用程序部署到去中心化的状态机上。这意味着,每个想构建区块链应用的人,都会在共享状态机上部署代码。


前端几乎保持不变,有一些特殊例子将会在后文介绍。


以下是该架构示意图:


详细说明:

我们具体分析一下:


1)区块链


以太坊上的区块链世界是今天的当红炸子鸡:因为以太坊是全球可访问的、具有确定性的状态机,由点对点(Peer to Peer)的节点网络共同维护。以太坊状态机上的状态变化,是由网络的参与者遵循的共识规则所控制的。


所以,以太坊的设计,就是一个世界上任何人都可以访问、写入的状态机。因此,以太坊不属于任何单个实体,而是由网络中的每个参与者共同拥有。


注意,数据写到以太坊区块链上,就不能再被更改。


2)智能合约


智能合约是一个在以太坊区块链上运行的程序,智能合约定义了区块链上发生的状态变化背后的逻辑。智能合约是用高级语言(编程语言)编写的,如Solidity或Vyper。



由于智能合约代码存储在以太坊区块链上,所以任何人都可以检查网络上所有智能合约的应用逻辑。


3)以太坊虚拟机(Ethereum Virtual Machine)缩写为EVM


啥是虚拟机呢? 


就是计算机系统的仿真器,可以在一个完全隔离的系统中,提供我们真实计算机的功能。


系统虚拟机可以提供一个可以运行完整操作系统的完整系统平台,例如我们用的Windows系统。MAC OS系统等。 


程序虚拟机就是,可以在仿真器里单独运行计算机程序。 


也就是说,如果购买了云服务商提供的虚拟机,就像从云服务商那里买了一块地,之后就可以在虚拟机上面安装各种软件和运行各种任务,就像我们在自己买来的土地上自由改造,盖房子一样。


接下来,通过以太坊虚拟机,可以执行智能合约中定义的逻辑,处理以太坊(全球可访问)状态机上发生的状态变化。


EVM不理解像Solidity和Vyper这样的高级语言,这些语言被用来编写智能合约。相反,必须将高级语言编译成Bytecode,EVM才可以执行。


4) 前端


最后,在前端这块。前端定义了用户界面逻辑,但前端也会与智能合约中定义的应用逻辑进行交互。


前台和智能合约之间的通信比上图中的架构要稍复杂,那么,前端如何和以太坊的智能合约进行通信?


前端代码如何与以太坊的智能合约进行通信?


想要让前端与智能合约进行通信,进行功能调用:但是,我们知道Ethereum是一个去中心化的网络,网络中的每个节点都保留着以太坊状态机上所有状态的副本,包括与每个智能合约相关的代码和数据。
想与区块链上的数据和代码互动时,就需要与节点们的其中一个互动。这是因为,任何节点都可以广播请求在EVM(以太坊虚拟机)上执行一个交易。然后,矿工会执行该交易,并将产生的状态变化广播至网络的其他部分。


有两种方法来广播(公布/确认)一个新的交易。


  • 构建自己的在以太坊区块链上的节点,运行以太坊区块链软件

  • 应用第三方服务如如Infura和Alchemy提供的节点,如Infura和Alchemy


如果应用用第三方服务,就不必应付自己运行一个完整节点的麻烦。毕竟在自己的服务器上设置一个新的以太坊节点可能需要几天时间。(很多数据需要同步,甚至会占用比普通笔记本电脑所能处理的更多带宽和存储空间)。
此外,随着DApp规模的扩大,存储完整的以太坊区块链的成本会上升,就需要增加更多的节点来拓展基础设施。这就是为什么,随着基础设施变得更加复杂,需要全职的DevOps工程师,工程师可以帮助维护基础设施,确保可靠的正常运行时间和快速响应时间。
综上所述,为了避免这些麻烦事,许多DApps就会选择使用Infura或Alchemy等服务来管理节点基础设施。当然,这是有代价的(有机会进一步讨论这个问题)
接着讲一下供应商。当需要与区块链互动时,所连接的节点(无论是自己设置的还是使用)



每个以太坊客户端(Provider)都遵循了JSON-RPC规范(解释)。这确保当前端应用程序想要与区块链交互时,有一套统一方法。JSON-RPC是一个无状态、轻量级的远程程序调用(RPC)协议,定义了几个数据结构及其处理规则。它与传输无关,因此这些概念可以在同一进程中使用,通过套接字,通过HTTP,或在许多不同的消息传递环境中使用。它使用JSON(RFC 4627)作为数据格式。

 一旦通过Provider连接到区块链,我们可以读取存储在区块链上的状态。但如果想写入状态,在向区块链提交交易之前,还需要做一件事-,这就是用私钥 "签署 "交易。举个例子:设想有一个DApp,用户可以阅读或发布博客文章到区块链上,在前端有一个按钮,任何人都可以查询某个特定用户写的博客文章。(回顾一下,从区块链上阅读并不要求用户签署交易)。 
然而,当一个用户想在链上发布一个新的帖子时,这个DApp就会要求用户使用他们的私钥 "签署 "交易,只有在那时,DApp才会将交易转发到区块链上。否则,节点将不接受该交易。这种交易的 "签名 "是Metamask的典型作用(MetaMask 是一个开源的以太坊钱包,能帮助用户方便地管理自己的以太坊数字资产)



Metamask是一个工具,通过它,应用程序能够轻松处理密钥管理和交易签名。Metamask会在浏览器中存储用户私钥,每当前端需要用户签署交易时,就会调用Metamask。


Metamask提供与区块链的连接(作为 "Provider"),因为它已经有了与Infura提供的节点的连接,因为它需要它来签署交易。这样一来,Metamask既是一个提供者,也是一个签署者( Signer)。


基于区块链的存储


构建一个应用程序,所有的智能合约和数据可以在以太坊区块链上运行,这种架构是有意义的。但任何在以太坊上写过应用程序的人都知道,区块链上的存储成本非常高。
这是为什么呢?
原来,在以太坊上,用户每次向区块链添加新数据时都要付费。这是因为在去中心化的状态机上增加一个状态,会增加维护该状态机节点的成本。
每次用户的交易需要添加新的状态时,要求用户为使用我们的DApp支付额外的费用,这样的用户体验不优质。解决这个问题的方法之一,是应用分散的链外存储解决方案,如IPFS或Swarm。
IPFS:星际文件系统(InterPlanetary File System); IPFS 是一个分布式的Web, 点对点的超媒体协议。IPFS系统不是将数据存储在一个集中的数据库中,而是将数据分布和存储在一个点对点的网络中,需要时很容易就可以检索到。
IPFS 还有一个名为“Filecoin”的激励层。通过Filecoin,世界各地的节点可以存储和检索这些数据。可以通过Infura或 Pinata(which provides an easy-to-use service where you can “pin” your files to IPFS and take the IPFS hash and store that on the blockchain)这种开箱服务,可以将文件“钉”到IPFS上,然后把IPFS哈希保存,存到区块链上。
Swarm也是类似的,它是一个去中心化的存储网络,但有一个明显的区别。Filecoin是一个独立的系统,而Swarm的激励系统是内置的,通过以太坊区块链上的智能合约执行,用于存储和检索数据。
所以现在,架构中加上IPFS或Swarm,应用架构看起来如下图所示:



聪明读者可能发现了:在图中,前端代码没有存储在区块链上。我们可以把这段代码托管在AWS(亚马逊云服务)上,在Web 2.0中通常会这么做,但这样一来,就会为DApp创造了一个中心化的卡点如果AWS瘫痪了怎么办?如果云计算会检查我们的应用程序怎么办?

所以,如果我们想建立一个真正的去中心化的应用程序,可能会选择在一个去中心化的存储解决方案上托管你的前端,如IPFS或Swarm。
所以现在我们应用架构看起来会如下图所示:


在区块链中进行查询:


到目前为止,本文讲述了如何通过签署交易,然后发送至区块链上。但如何从区块链上的智能合约中读取数据呢?有两种主要方式可以做到这一点:
1)智能合约事件(Smart Contract Events)
使用Web3.js库来查询和监听智能合约事件。可以监听特定的事件( listen for smart contract events),并在每次事件被触发时指定一个回调emit an event )。例如,如果我们有一个智能合约,每个区块都会从A向B发送一个连续的支付流(continuous payment stream),那么就可以在每次向人B支付新的款项时发出一个事件。前端代码可以监听智能合约发送的事件,并根据它执行具体的行动。
2)索引(The Graph
上述方法存在一些限制。例如,如果部署了一个智能合约,后来突然需要一个最初没有包括的事件,怎么办?必须用该事件和数据重新部署一个新的智能合约。此外,使用回调来处理各种UI逻辑很快就会变得非常复杂。
在这种场景下, "The Graph"索引就可以发挥作用。
The Graph是一个链外索引解决方案,可以更容易查询以太坊区块链上的数据。
 The Graph允许我们定义哪些智能合约需要索引,哪些事件和函数调用需要监听,以及如何将传入的事件转化为前端逻辑(或需要调用API的业务)可以消费的实体。它使用GraphQL作为查询语言,许多前端工程师喜欢这种语言,因为与传统的REST API相比,表达能力相对很强。
(解释:GraphQL:FB推出的一种代替rest方法的新结构查询语法)
通过索引区块链数据,The Graph让我们在应用逻辑中以低延迟查询链上数据。
现在,DApp架构看起来如下图所示:


然后我们要聊一下扩展性(Scaling)
解释:以太坊的Gas是什么?
Gas其实就是邮费。如果我们去邮局给别人寄信,需要贴邮票,支付邮费,对于以太坊网络也是一样,给别人转账或者调用合约,需要支付gas费。所以gas就相当于邮局的邮费。


DApp的扩展(Scaling)

Ethereum average gas price


Average transaction fee


Average block size


很明显,这里有一个问题,由于各项成本相对较高,在以太坊上建立一个具有高GAS费用和全区块的DApp会导致一个非常糟糕的用户体验。值得庆幸的是,有一些解决方案正在开发中。
一个流行的扩展解决方案是Polygon,一个L2扩展解决方案。Polygon没有在主区块链上执行交易,而是有 "侧链 "来处理和执行交易。侧链是一个二级区块链,与主链对接。每隔一段时间,侧链就会将其最近的区块聚合起来提交给主链。


L2解决方案的其他例子是Optimistic Rollups 和zkRollups。这里的构思是类似的:使用 "Roll "智能合约在链外批量交易,然后定期将这些交易提交到主链上。
L2解决方案在链外进行交易,只在链上存储交易数据。这就可以对区块链进行扩展,我们不需要在链上执行每一笔交易。这也使得交易更快、更便宜,而且在必要时,仍然可以与主以太坊区块链进行通信。
综上
综上所述:
如果觉得上述稍显复杂,你并不是一个人:)将所有工具拼凑在一起是很复杂的,可能会带来艰难的开发者体验。但不必担心,逐渐会产生新的开发者框架,这些框架会改善开发体验。
例如,开发框架Hardhat是,使以太坊开发者更容易建立、部署和测试智能合约。Hardhat提供了 "Hardhat网络",开发者可以用它来将他们的智能合约部署到本地网络上--而不需要处理实时环境。更好的是,它提供了一个伟大的插件生态系统,使开发者的生活更加轻松。Hardhat还提供了console.log()功能,类似于JavaScript,用于调试目的。
当然,这仅仅是个开始。我希望我们在未来能继续看到更好的开发者工具。


总结


大多数人花了几个月的时间来弄清楚工具链是如何工作的,所以如果读到本文的朋友是一个新的DApp开发者,希望这篇文章能为你节省一些时间。
*谢谢卫Sir、老汪、Stanley对问题的耐心解答
原文链接1.https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application
如果您对Web3或区块链技术有什么想法,欢迎在后台留言,兔兔看到会加您微信:)期待可以和有缘看到本文的朋友共同进步:)


公众号后台回复:【JS】,可以获得兔兔送你的礼物:web3.js Documentation


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存