当前位置: 首页 > 科技观察

Dapp后台架构、安全与设计模式

时间:2023-03-14 23:45:47 科技观察

本文转载自微信公众号《区块链研究实验室》,作者连三丰。转载本文请联系区块链研究实验室公众号。去中心化应用程序(DApps)需要特殊的系统设计来实现高安全性和可靠性。在本文中,我将以以太坊为主要示例,介绍如何为去中心化应用程序正确设计和实施后端和智能合约的几个主要原则,尽管其中大部分将适用于Eos、Tron和其他去中心化应用程序。数据平台。文章重点:如何在不考虑安全的情况下将私钥存储在后端如何合理设计智能合约和“去中心化”内容去中心化和半去中心化应用架构示例如何处理网络负载和故障等底层问题让我们开始吧!1.去中心化程序和区块链尽管区块链在今天面临着许多采用和监管方面的困难,但无论是算法,无论是区块链、哈希图、速度还是其他,与任何分布式账本技术一样,它是一项永恒的技术。区块链和其他类似技术带来的主要价值可以概括如下:它们使人们能够编写和运行程序,这些程序在创建后在实践中无法更改,在执行过程中也无法篡改。换句话说,这些程序始终按设计运行,任何一方都无法影响它们的行为。如果我们将它们视为定义硬币如何来回转移的程序,则此定义适用于当今存在的许多加密货币。这也解释了为什么加密货币和多种代币具有真正的价值:它们不能通过定义的“底层程序”凭空创造。与比特币相比,Ethereum/EOS/Tron/……平台实现了更复杂的程序层,程序层又实现了执行环境,允许任何人在平台之上编写自己的去中心化程序。用户自定义程序始终按设计运行,无任何异常,并由平台保证安全。2.去中心化应用程序这些在去中心化网络上运行的安全且不可变的程序与传统的前端和后端技术相结合,如今被称为去中心化应用程序(DApps)。虽然其中一些可以是半集中的,但真正分散的应用程序中的大部分活动应该在中央控制下进行。如果有人让我画出今天的DApps是如何工作的,我可能会画这幅图想象一下我们今天所说的去中心化应用程序,以任何现有的中心化网络资源如_YouTube_或_instagram_为例,并想象将你的“加密身份”绑定到一个Web/移动资源,而不是受密码保护的集中帐户。这就是电子钱包软件为您提供的。身份的私钥(秘密,你可以代为操作)存储在设备本地,永远不会上线,因此没有人可以控制这个身份。有了这个身份,你就可以在集中式和分散式(与传统的WWW不同的网络,其目标是消除中央权威)网络(中央权威控制网络资源)中进行不同的操作,并将站点与作为访问点和/或图形用户界面。这种“密码身份”的全部意义在于,您的行为受到密码保护,没有人可以更改您签署的内容或您签署的内容。如今,以太坊、EOS或Tron等容错去中心化网络的计算和存储能力受到限制。如果它们是可扩展的,我们可以使用去中心化网络来存储整个去中心化应用程序,包括它们的GUI、数据和业务逻辑。在这种情况下,我们将这些应用程序称为真正去中心化/分布式应用程序。然而,由于这些网络目前不可扩展,我们结合不同的方法来为我们的应用程序实现最大程度的去中心化。正如我们所知,“遗留”后端没有任何发展。例如:我们使用后端来托管去中心化应用程序的前端。我们使用后端与任何其他现有技术和服务集成。一个真正世界级的应用程序不能孤立存在。我们使用后端来存储和处理任何足以去中心化网络的东西,尤其是区块链。事实上,整个应用程序及其业务逻辑都存储在世界的某个地方,除了区块链部分。更不用说,IPFS和类似的存储层不保证文件的可访问性,因此我们不能依赖它们而不自己托管文件。换句话说,始终需要专用的运行服务器。到目前为止,如果不使用可靠的后端,就不可能构建安全和部分去中心化的应用程序,本文的重点是解释如何正确地做到这一点。3.(去中心化)和代币碰巧的是,当今几乎所有去中心化应用程序都是围绕所谓的代币构建的,这些代币是驱动特定去中心化应用程序货币定制(或只是简单克隆)的加密。代币只是一种可编程的货币或资产,仅此而已。代币智能合约决定了用户如何转移代币,而应用智能合约可以扩展代币智能合约所缺少的一切。两种类型的智能合约都在去中心化网络之上运行。通常,代币是写在像以太坊这样的去中心化平台之上的“智能合约”。通过拥有一些令牌,您基本上可以在Web资源或移动应用程序上获得不同的服务,并用该令牌交换其他东西。这里的关键点是令牌本身存在并且不受中央机构控制。有许多围绕代币构建的应用程序示例:从众多收藏游戏,例如CryptoKitties(ERC721代币),到面向服务的应用程序,例如LOOMNetwork,甚至浏览器,例如Brave和类似DreamTeam(ERC20兼容代币)之类的游戏平台。由开发人员自己决定和决定他们将(或不会)对其应用程序拥有多少控制权。他们可以在智能合约之上构建整个应用程序的业务逻辑(就像CryptoKitties所做的那样),或者,他们根本不使用智能合约,将所有内容集中在服务器上。但是,最好的方法是将其居中。4.去中心化网络的后端从技术的角度来看,必须有一个连接代币和其他智能合约与网络/移动应用程序的桥梁。在当今完全去中心化的应用程序中,客户端直接与智能合约交互,此桥被简化为像Infura这样的节点池的公共API或JSONRPCAPI函数,因为并非每个设备都可以运行和支持其各个网络节点。但是,此API仅提供一组基本且非常狭窄的功能,这些功能仅允许进行简单的查询或高效的数据聚合。所以最终引入了自定义后端,使应用程序成为半中心化的。与去中心化网络的整个交互可以缩小到一两点,具体取决于应用程序的需要:监听网络事件(例如令牌传输)/读取网络状态。发布交易(调用状态改变智能合约功能,例如代币转账)。这两个方面都很难实现,尤其是当我们想要构建一个安全可靠的后端解决方案时。以下是我们要分解的要点:首先,在以太坊中,不支持开箱即用的事件检索。原因有很多:网络节点在获取大量事件时可能会失败,事件可能会因网络分叉而消失或改变等。我们必须构建一个抽象层来同步网络中的事件并确保它们的可靠传递。与交易发布一样,我们必须抽象出以太坊的低端内容,例如nonce计数器和gas估算,以及交易重新发布,以提供可靠和稳定的接口。此外,交易发布意味着使用私钥,这需要高级后端安全性。安全。我们会认真对待并面对这样一个事实,即无法保证私钥永远不会在后端泄露。幸运的是,有一种方法可以设计甚至不需要高度安全的后端帐户的去中心化应用程序。在我们的实践中,所有这些导致我们为以太坊创建了一个强大的后端解决方案,我们将其命名为以太坊网关。它从其他微服务中抽象出以太坊的乐趣,并提供可靠的API来使用它。以太坊的后端监控。监视器显示的活动主要与我们的定期计费功能有关(尽管您可以看到每小时的峰值)。5.去中心化应用架构这部分高度依赖于具体去中心化应用的需求。我们将尝试在构建这些应用程序的基础上梳理出一些基本的交互模式(D平台=去中心化平台=Ethereum/EOS/Tron/Whatever):ClientPlatform:FullyDecentralizedApplications。客户端(浏览器或移动应用程序)在以太坊“钱包”软件(如Metamask、Trust)或硬件钱包(如Trezor或Ledger)的帮助下直接与去中心化平台对话。以这种方式构建的DApp示例包括CryptoKitties、Loom的委托调用、加密钱包本身(Metamask、Trust、Tron钱包等)、去中心化加密交易所(如Etherdelta)等。D平台?客户?后端?D-Platform:集中式或半集中式应用。客户端与分散的平台和服务器交互,几乎没有共同之处。一个很好的例子是当今的任何(集中式)加密货币交易所,例如BitFinex或Poloniex:您在交易所交易的硬币仅记录在传统数据库中。您可以通过将资产发送到特定地址(“平台?客户端”)来“充值”您的数据库余额,然后在应用程序(后台?D平台)中执行一些操作后提取资产,但是,您所做的一切取决于“应用程序”本身(客户端?后端)并不意味着您直接与3D平台交互。另一个例子是Etherscan.io,它使用半中心化的方法:你可以在那里做所有有用的去中心化操作,但如果没有他们全面的后端,应用程序本身就毫无意义(Etherscan不断同步交易、解析数据并存储它,最终提供一个全面的API/UI)。介于两者之间:静态、集中式或半集中式应用程序。结合以上方法。例如,我们可以有一个应用程序提供各种服务以换取加密,允许您使用加密身份登录和签署信息。希望完全分散的应用程序(客户端平台)的交互模型不会造成任何问题。借助Infura或Trongrid等出色的服务,您可以轻松构建根本不需要服务器的应用程序。与几乎任何客户端库(如用于以太坊的Ethers.js或用于Tron的TronWeb)一样,您可以连接到这些公共服务并与网络通信。但是,对于更复杂的查询和任务,您可能仍需要分配自己的服务器。涉及后端的其余交互模式使事情变得更加有趣和复杂。为了可视化所有这些,让我们想象一下后端对网络中的某些事件做出反应的情况。例如,用户发布配额交易,允许我们向他们收取费用。要收取费用,我们必须为发出的配额事件发布费用交易:服务器对去中心化网络中用户操作的反应流程示例从后端的角度来看,会发生以下情况:我们通过不断轮询来监听特定网络网络事件。收到事件后,我们将执行一些业务逻辑,然后决定发布一个交易作为响应。在发布交易之前,我们要确保它可以被挖掘(在以太坊中,成功的交易gas估计意味着相对于当前网络状态没有错误)。但是,我们不能保证交易会被成功挖掘。使用私钥,我们签署并发布交易。在以太坊中,我们还必须确定交易的gasprice和gaslimit。交易发布后,我们会不断轮询网络的状态。如果时间太长,我们没有得到交易的状态,我们必须重新发布它或触发“失败条件”。交易可能因各种原因而丢失:网络拥塞、节点掉线、网络负载增加等。在以太坊中,您还可以考虑使用不同的(实际)gas价格重新签署交易。完成交易后,如果需要,我们可以执行更多业务逻辑。例如,我们可以通知其他后端服务关于交易已经完成的事实。此外,考虑在对交易做出最终决定之前等待多次确认:网络是分布式的,因此结果可以在几秒钟内改变。如您所见,发生了很多事情!但是,您的应用程序可能不需要其中的某些步骤,具体取决于您要实现的目标。但是,构建强大而稳定的后端需要解决上述所有问题。让我们分解一下。6.去中心化应用后端这里我想强调一些出现大部分问题的要点,即:监听网络事件和从网络读取数据发布交易以及如何安全地进行交易7.监听以太坊中的网络事件As在其他去中心化网络中,智能合约事件(或事件日志,或只是日志)的概念允许链下应用程序了解区块链中发生的事情。这些事件可以由智能合约开发人员在智能合约代码中的任何位置创建。例如,在众所周知的ERC20代币标准中,每一次代币转账都必须记录一个Transfer事件,让链下应用程序知道代币转账已经发生。通过“监听”这些事件,我们可以执行任何(重新)操作。例如,当令牌转移到您的地址时,一些移动加密钱包会向您发送推送/电子邮件通知。事实上,没有开箱即用的可靠解决方案来监听网络事件。不同的库允许您跟踪/收听事件,但是,在许多情况下,可能会出现错误,导致事件丢失或未处理。为了避免丢失事件,我们必须构建一个自定义后端来维护事件同步过程。根据您的需要,实施可能会有所不同。但这里给大家一张图是如何根据微服务架构构建可靠的以太坊事件传递的选项之一:Reliabledeliveryofethereumeventstoallbackendservices这些组件以如下方式工作:EventsaresynchronizedbackendservicesconstantlyPollthenetwork尝试检索新事件。一旦有一些新事件可用,它将把这些事件发送到消息总线。事件成功提交到消息总线后,对于区块链而言,我们可以保存上一个事件的区块,以便下次从这个区块请求新的事件。请记住,一次检索太多事件可能会导致请求总是失败,因此您必须限制从网络请求的事件/块的数量。消息总线(例如RabbitMQ)将事件路由到为每个后端服务单独设置的每个队列。在事件发布之前,事件同步后端服务指定路由键(例如,智能合约地址+事件主题),消费者(其他后端服务)创建仅订阅特定事件的队列。因此,每个后端服务只获取它需要的那些事件。此外,消息总线确保所有事件在传递之前都发布到事件总线。当然,您可以使用其他方式代替消息总线:HTTP回调、套接字等。在这种情况下,您需要弄清楚如何确保自己提供回调:管理索引/自定义回调重试、实现自定义监控.8.发布交易为了向去中心化网络发布交易,我们必须执行几个步骤:准备交易。与交易数据一起,此步骤意味着请求网络状态以查明此交易是否有效以及是否将被挖掘(以太坊中的gas估计)和交易的序列号(以太坊中的随机数)。一些图书馆尝试在幕后执行此操作,但是,这些步骤很重要。签署交易。此步骤意味着使用私钥。您很可能会在此处嵌入自定义私钥组装解决方案。发布和重新发布交易。这里的关键点之一是,您发布的交易总是有可能从去中心化网络中丢失或丢失。例如,在以太坊中,如果网络的gas价格突然上涨,已发布的交易可能会被丢弃。在这种情况下,您必须重新发出交易。此外,您可能希望使用其他参数重新发布交易(至少在gas价格较高的情况下),以便尽快完成交易。因此,如果替换交易之前没有预先签名(使用不同的参数),重新发布交易可能意味着重新签署它。以上关于以太坊交易发布的几点可视化通过使用上述方法,您最终可以构建类似于下面序列图中所示的东西。在这个特定的序列图中,我将演示(一般!)区块链循环计费的工作原理:用户在智能合约中执行一个功能,最终允许后端执行成功的费用交易。特定于任务的后端服务监听计费限制事件并发布计费交易。一旦费用交易被挖掘,特定于任务的后端服务从以太坊网络接收事件并执行一些逻辑(包括设置下一个费用日期)。区块链循环计费如何工作的一般序列图,显示后端服务与以太坊网络后端安全和智能合约之间的交互。发布交易总是涉及使用私钥。您可能想知道是否可以保证私钥的安全。有许多复杂的策略和不同类型的软件可以非常安全地将私钥存储在后端。一些私钥存储解决方案使用地理分布的数据库,而另一些甚至推荐特殊的硬件。然而,无论如何,半中心化应用程序最容易受到攻击的地方是组装私钥并用于签署交易(或者,在特殊硬件的情况下,触发交易签署过程)的地方。因此理论上没有100%可靠的解决方案来提供防弹保护以防止泄露存储的私钥。