使用 Gear 必须掌握的技术|Gear Wiki

导语

GearFans
12 min readMar 2, 2023

本篇文章我们将为你介绍 Gear 使用的 Actor 模型、Substrate 框架、WebAssembly、持久内存的概念及工作方法、Gear 状态组件,以帮助你更好的了解 Gear。

Actor 模型

在并行计算系统中,“消息通信” 意味着程序通过消息交换进行通信。它比 “共享内存通信” 更具有优势。消息传递并发比共享内存并发更容易理解。它通常被认为更健壮,比共享内存具有更好的性能。

对于进程间通信,Gear 使用 Actor 模型方案。Actor 模型的原则是,程序从不共享任何状态,只是在彼此之间交换信息。

通过 Actor 模型,系统由同时运作的对象组成,这些对象之间完全通过消息传递进行交流。虽然普通的 Actor 模型不保证消息的顺序,但 Gear 提供了一些额外的保证,即两个特定程序之间的消息的顺序被保留下来。

在 Actor 模型中,一个系统由同时运作的功能对象组成,这些对象之间完全通过消息传递进行通信。虽然一般 Actor 模型并不保证消息的顺序,但 Gear 提供了一些额外的保证,即两个特定程序之间的消息顺序被保存下来。

Actor 模型保障了高可扩展性和高容错性。

Actor

Actor 模型中的 Actor 是可以发送和接收消息的原子计算单元。在 Gear 中,Actor 是一个程序 (智能合约) 或向程序发送消息的用户。每个 Actor 都有一个内部私有状态和一个信箱。通信是异步的,消息从信箱中弹出并分配给消息处理流,在那里按周期处理。

当一个 Actor 收到并处理一个消息时,可以响应以下内容:

  • 向另一个 Actor 发送消息
  • 创建另一个 Actor
  • 改变自己的内部状态

Actor 是独立的,它们从不分享任何状态,只是相互交换信息。

使用 Actor 模型方案提供了一种在程序(智能合约)逻辑中实现基于 Actor 的并发性的方法。它可以利用各种语言构造进行异步编程(Rust 中的 Futures 和 async-await)。

Async/await 支持

与类不同,actor 一次只允许一个任务访问它们的可变状态,这使得多个任务中的代码可以安全地与同一个 actor 实例交互。

异步函数大大简化了并发管理,但它们无法处理死锁或状态损坏的情况。为了避免死锁或状态损坏,异步函数应该避免调用可能阻塞其线程的函数。为了实现这一点,他们选择使用 await 表达式。

目前,典型的智能合约代码中缺乏对 async/await 模式的支持,这给智能合约开发人员带来了很多问题。实际上,通过手工添加函数(在 Solidity 智能合约中),以在智能合约程序流中实现更好的控制的方式,或多或少是可行的。但是问题在于,一些合约中的函数会让人们很容易混淆在合约生命周期中的哪个阶段可以调用哪个函数。

Gear 为程序提供了通用的 async/await 语法。它极大地简化了开发和测试,并减少了智能合约开发中出错的可能性。如果程序逻辑需要,Gear API 也允许通过简单地不使用 await 表达式来使用同步消息。

Substrate

Substrate 是一个模块化框架,通过组合定制或预先构建的组件,可以创建独特的区块链。

从名字上很容易理解 Substrate 的功能。Substrate 是一个模板,提供了开箱即用的可扩展能力,包括共识机制、治理功能、Wasm 等等。

Substrate 有以下几个功能:

  • 无分叉升级
  • 内部协调(Built-in Coordination)
  • 基于 WebAssembly 的跨语言支持
  • 对轻客户端友好
  • 最终一致性
  • 无缝集成

Substrate 使我们能够大大减少开发时间,并专注于开发主要的 Gear 组件。Rust 保证了程序的安全性和高性能。

更多关于Substrate的内容,请看 https://www.substrate.io/

什么是 WebAssembly(Wasm)

WebAssembly 是一种将 JavaScript 以外的编程语言的应用程序作为网页运行的方式。从本质上讲,Wasm 只是一个在所有现代浏览器上运行的虚拟机,但在过去,你需要使用 JavaScript 来运行网页中的代码,而 Wasm 使你有可能在 JavaScript 以外的编程语言的浏览器中运行代码。

由于技术的特殊性,WebAssembly 虚拟机,简称 Wasm,被证明比任何其他虚拟机都快。WebAssembly 的使用使 Gear 的智能合约能够直接编译成机器代码,并以接近原生的速度运行。更高的速度意味着更低的交易成本和更高的效率。

所有 Gear 程序和智能合约都是作为 WebAssembly 程序运行的。这意味着,例如,开发人员可以将他们的应用程序带到网络上,并在网络浏览器中实现应用程序的全部性能--它们通常在 Windows 或 Mac 上运行原生程序时具有的性能。开发人员实际上也不必直接编写 Wasm 代码。相反,他们将使用 Wasm 作为用其他语言编写的程序的编译目标。

Wasm 解决的主要问题是无法在网络上使用 JavaScript 以外的编程语言。虽然 JavaScript 是一种伟大的编程语言,但它的设计并不是为了在大型应用程序中实现超高速。Wasm 改变游戏规则的地方在于,它以一种完全安全的方式将用其他编程语言编写的本地应用程序的性能带到了网络上。

Wasm 应该在两个主要方面提供显著的速度提升。首先,它应该大大增加应用程序的启动速度。事实上,已经使用 Wasm 的应用程序已经能够将应用程序的启动时间减少一半,而且随着更多的优化,它只会继续进一步提高启动速度。这将使巨大的应用程序能够非常、非常迅速地加载起来。其次,Wasm 在吞吐量方面也有很大的好处,这意味着一旦代码被编译,它的运行速度会更快--使应用程序更有效,反应更快,这将大大改善用户体验。

WebAssembly 有以下优点:

  • Wasm 是非常快速、高效和可移植的。代码可以在不同的平台上以接近原生的速度执行。
  • Wasm 也是可读和可调试的。虽然 WebAssembly 是一种低级语言,但它确实有一种人类可读的文本格式,可以用手写、查看和调试代码。
  • 它也是非常安全的,因为它是在一个安全的沙盒环境中运行的,像其他网络代码一样,它将执行浏览器的同源和无权限安全策略。
  • Wasm 格式允许 Gear Protocol 的开发者现在使用 Rust 开发,未来 C#/C++、Go 和 Javascript 也可以编写应用程序。

持久化内存

Gear Protocol 的另一个突出特点是持久性内存方法。它使开发更容易,消除了很多复杂性,并使协议内存管理与实际硬件和操作系统相匹配。

在 Gear 网络中运行的程序不使用存储,而是将全部状态持久化,这确保了区块链上下文的 API 面要小得多。它避免了特定领域的语言特征,也允许使用更复杂的语言结构--持久化的闭包、合成器等。

Gear Protocol 使用了巧妙的内存虚拟化技术 (尽管普通的 Wasm 没有),内存分配和回收是该协议的第一等系统调用,还会跟踪内存访问,只加载/存储所需的内存页。这使得存储在区块链状态中的智能合约的堆栈框架(通常在期货及其合成器中发现)能够被无缝持久化,并在需要时被调用,在请求时保留其状态。

程序代码存储为一个不可变的 Wasm blob。每个程序都有固定数量的内存,在消息处理之间存在 (所谓的静态区域)。

Gear 实例持有每个程序的单独内存空间,并保证持久性。一个程序只能在它自己的内存空间内进行读写,不能访问其他程序的内存空间。单独的内存空间在程序初始化期间为其保留,不需要额外的费用(它包含在程序的初始化的费用中)。

程序可以按 64KB 的块分配所需的内存量。每个内存块分配都需要 gas 费。每个页面 (64KB) 单独存储在分布式数据库后端,但在运行时,Gear 节点构造连续运行时内存,并允许程序在其上运行而无需重新加载。

内存并行

每个程序单独的独立内存空间允许 Gear 节点上的消息处理并行化。并行处理流的数量等于 CPU 核数。每个流处理用于一组已定义程序的消息。它涉及从其他程序或外部发送的消息 (用户事务)。

例如,给定一个消息队列,其中包含针对 100 个不同程序的消息,Gear 节点运行在一个配置了 2 个处理线程的网络上。Gear 引擎使用运行时定义的流数量 (等于一个典型的验证机上的 CPU 核的数量),将目标程序的总数除以流的数量,并为每个流创建一个消息池 (每个流 50 个程序)。

程序被分发到不同的流中,每个消息出现在定义了目标程序的流中。因此,所有发给特定程序的消息都出现在一个处理流中。

在每个周期中,目标程序可以有多个消息,一个流处理大量程序的消息。消息处理的结果是来自每个流的一组新消息被添加到消息队列中,然后循环往复。在消息处理过程中生成的结果消息通常被发送到另一个地址 (返回原点或下一个程序)。

状态组件

与任何区块链系统一样,Gear 保持分布式状态。编译为 WebAssembly 的运行时代码,成为区块链存储状态的一部分。

Gear 确保了其中一个决定性的特征--无障碍运行时升级。如果使用终结性小工具,状态也可以保证被终结。

存储状态由以下组件组成:

  • 程序和内存(包括程序代码和私有内存)
  • 消息队列(网络的全局消息队列)
  • 账户(网络账户及其余额)

程序

程序是 Gear 网络状态下的头等公民。

程序代码存储为不可变的 Wasm 二进制文件(blob)。每个程序都有固定数量的内存,在消息处理之间保持不变(所谓的静态区域)。

程序可以从 Gear 实例提供的内存池中分配更多内存。一个特定的程序只能在专门分配给它的内存中读写。

内存

每个程序都有固定的内存大小,Gear 允许对其进行控制。程序只能在其内存中读写,不能访问其他程序的内存空间。每个程序都有独立的内存空间,可以在 Gear 节点上并行处理消息。

程序可以以 64KB 的块为单位分配所需的内存量。每个内存块分配都需要 gas 费。每个页面(64KB)单独存储在分布式数据库后端,但在运行时,Gear 节点构建连续运行时内存并允许程序在其上运行而无需重新加载。

消息队列

Gear 实例拥有一个全局消息队列。使用 Gear 节点,用户可以将带有一条或多条消息的交易发送到特定程序。这会填满消息队列。在块构造期间,消息出列并路由到特定程序。

账户

对于公共网络,防止 DOS 攻击总是需要 gas/fee 来处理交易。Gear 提供了一个 balance 模块,允许存储用户和程序的余额并支付交易费用。

一般来说,一个特定的 Gear 网络实例可以定义为有许可和无许可的公共区块链。在许可场景中,不需要 balance 模块。

状态转移

每个系统都遵循系统状态演变所依据的规则。当网络处理新的输入数据时,状态会根据状态转换规则前进。这些输入数据被打包在被称为交易 (transactions) 的细粒度信息中。

Gear 节点维护和同步一个交易池,其中包含所有新交易。当任何节点(无论是否为验证者)收到一个交易时,该节点会将这个交传播给所有连接的节点。关于交易池如何运作的更高级内容,请参考 Substrate 文档 。链接替换为 https://docs.substrate.io/v3/concepts/tx-pool/

当 Gear 验证节点生成新块时,池中的一些(或所有)交易将合并到一个区块中,网络将通过该块进行状态转换。在生成下一个块之前,上一个块中未打包的交易将保留在池子中,直到产生下一个区块。

Gear 网络支持以下类型的交易:

  1. 上传程序 - 用户上传新的程序(智能合约)
  2. 上传代码 - 用户上传代码,以便以后用它来3. 创建程序 - 程序或用户根据先前上传的代码创建一个程序
  3. 发送消息 - 程序或用户将消息放入消息队列
  4. 发送回复消息 - 与消息类似,但只能作为对收到的信息的回复来发送
  5. 从 mailebox 提款 - 用户要求提走与他的 mailbox 中的信息相关的余额
  6. 取出消息 - 验证器(区块生产者)对多个信息进行排队,运行相关程序
  7. 转账交易 - Gear 引擎执行 用户—程序—验证者 之间的转账交易

消息处理在块构建/导入时的预留空间中进行。它保证消息处理将在每个块中执行,并且至少以当前实例设置确定的某个特定速率执行。

上传程序

Gear 网络的指定机构 (或任何公开实现的用户) 可以提出一个新的程序保存到状态种。对于公共网络,还提供与程序相关的余额。这个新的余额将会设置为初始余额(存在抵押)。

上传代码

无需初始化即可上传 Wasm 代码。此代码不能作为程序执行,但它会保存到存储中,并可用于从中创建新程序。用户和程序都可以从上传的代码创建程序。

创建程序

用户和程序都可以从上传的代码创建新程序。代码可以多次重用以生成多个程序。

发送消息

终端用户通过向 Gear 网络发送信息与程序进行交互。发送到 Gear 网络的消息填充全局消息队列。这个队列可以被看作是一个运行时驱动的交易队列,但是要保证它接收的任何消息最终都会被处理。将消息放入队列不是免费的,因此可以保证消息会被发送。

程序之间也会交换消息。接收到的消息的结果可以是另一个消息 (回复),发送给另一个程序或用户或指定的行为,用于它接收到的下一个消息。一个程序还可以发送一个消息,其执行结果将是创建另一个程序。

发送回复消息

回复与上述消息类似,唯一不同的是,回复只能作为对收到的消息的回应而发送。用户可以将回复发送给他们 mailbox 中包含的信息。

从 mailbox 提款

在接收到具有关联的资产的消息后,用户必须提取资产,才能将其从消息转账到用户。未认领的将在邮件耗尽 gas 限制后离开 mailbox 后返回给发件人。

取出消息

当轮到验证器生成下一个区块时,验证者可以选择让哪些消息出列。它不需要每个特定的验证器来维护完整内存状态。出队列只发生在每个块的末尾。在退出队列期间,可以生成新的消息。它们也可以在此阶段被处理,但也可以留在队列中等待下一个块 (和另一个验证器)。

转账交易

常规转账交易可以通过两种方式进行。第一种方法是使用相应的外在因素 (例如transfer, setBalance等)。第二种方式是将一个用户的信息发送给另一个用户,并附附带相关的余额。

消息、区块和事件的生命周期

下图说明了 Gear 的全生命周期。正如面向通信领域的 actor 模型所规定的,除了消息可以共享,再没有任何东西是可以共享的了。以“系统”为目的地的消息最终会出现在事件日志中,以便在用户空间进行检查。

--

--

GearFans

Gear 是波卡生态的计算组件,GearFans 是 Gear 爱好者社区。