Sui 为什么选择 Move 语言?Sui Move 和 Core Move 有何区别?| Sui Wiki

在 Sui 中,开发者使用 Move 编程语言编写智能合约。本文列举了主要的 Move 资源,并比较了 Move 和 Solidity 编程语言,以及 Sui Move 和 Core Move 的区别。

Sui Move

首先,请注意 Move 基于得到良好支持的 Rust 编程语言。Sui Move 与 Core Move 的区别微妙而独特。以下是总结了 Sui Move 特点的一些资源(资源链接均在文末):

●Sui Move 公告
●Sui 源码
●rustdoc output
●Sui Move 案例解析

Move资源

这部分汇总了 Move 编程语言的外部资源链接。

●Zero Knowledge 频道的 Move & Sui 播客,其中详细描述了可编程对象。
●由 Sui 团队的一位成员撰写的 Move Book。
●Core Move 文档,包括:
●教程 - 编写一个 Move 模块的分步指南。
●书籍 - 涵盖各种主题的汇总页面。
●示例 - 一组示例,例如定义 token 和 token 的兑换。
●Awesome Move - 与 Move 相关的资源摘要,从区块链到代码示例。

Move 和 Solidity 的对比

目前,区块链语言领域的主要参与者是 Solidity。作为最早的区块链语言之一,Solidity 旨在使用大家熟知的数据类型(例如字节数组、字符串)和数据结构(例如哈希图)来实现基本的编程语言概念,并能够使用大家熟知的基础构建自定义抽象。

然而,随着区块链技术的发展,很明显区块链语言的主要目的是对数字资产进行操作,而这种语言的主要特点是安全性和可验证性(这是额外的安全层)。

Move 专为解决这两个问题而设计:数字资产的表示和对它们的安全操作。为了提供额外的保护,它与 Move Prover 验证工具共同开发。这允许 Move 开发者为其应用的关键正确性属性编写正式规范,然后使用验证器检查这些属性是否适用于所有可能的交易(transaction)和输入。

EVM 和 Move 之间的一个根本区别是资产的数据模型:
●EVM 资产被编码为 owner_address -> 哈希映射中的条目。资产更新和转移通过更新此映射中的条目来工作。没有代表资产的类型或值,因此资产不能作为参数传递、从函数返回或存储在另一个资产中。只有非结构化字节可以跨合约边界传递,因此每个资产都永远被困在定义它的合约中。

●Move 资产是任意用户定义的类型。资产可以作为参数传递,从函数返回,并存储在其他资产中。此外,由于 Move 内置的资源安全 1、2 保护,资产可以跨合约边界自由流动而不会失去其完整性。

Sui 大量利用 Move 数据模型来提高性能。Sui 的持久状态是一组可编程的 Move 对象,可以通过交易对其进行更新、创建和销毁。每个对象都有所有权元数据,允许 Sui 验证人使用该对象与因果不相关的交易并行执行和提交交易。Move 的类型系统可确保此所有权元数据在执行过程中的完整性。结果是开发者编写普通 Move 智能合约的系统,但验证人利用数据模型尽可能高效地执行和提交交易。

这对于 EVM 数据模型来说根本不可能。由于资产存储在可动态索引的映射中,因此验证人将无法确定交易何时可能触及同一资产。Sui 的并行执行和承诺方案需要像 Move 这样的语言,用词汇来描述可以跨合约自由流动的结构化资产。坦率地说:即使我们更喜欢 EVM/Solidity 而不是 Move,我们也无法在不牺牲使 Sui 独一无二的性能突破的情况下在 Sui 中使用它们。

Move 的主要优势之一是数据可组合性。始终可以创建一个新的结构(资产)Y,其中包含初始资产 X。更重要的是 —— 通过添加泛型,可以定义能够包装任何资产的通用包装器 Z(T),为包装的资产提供额外的属性或将其与其他资产组合。你可以在我们的 Sandwich 示例中了解可组合性是如何工作的。

Sui Move 和 Core Move 的区别

本文档描述了 Sui 编程模型,并强调了 Core(以前的 Diem)Move 语言和我们在 Sui 中使用的 Move 之间的区别。首先要记住,Move 是一门语言,而 Sui 是一个平台。

一般来说,为其他系统编写的 Move 代码可以在 Sui 中工作,但以下情况除外:

●全局存储运营商
●key 能力

以下是主要区别的总结:

●Sui 使用自创的以对象为中心的全局存储
●地址代表对象 ID
●Sui 对象具有全局唯一 ID
●Sui 有模块化初始器 (init)
●Sui 入口点将对象引用作为 input

每个改动的详细说明如下:

以对象为中心的全局存储

在 Core Move 中,全局存储是编程模型的一部分,可以通过特殊操作访问,例如 move_to、move_from 和更多全局存储操作符。资源和模块都存储在核心 Move 全局存储中。当你发布一个模块时,它会存储到 Move 内部新生成的模块地址中。当一个新对象(又名资源)被创建时,它通常也被存储到某个地址中。

但链上存储昂贵且有限(未针对存储和索引进行优化)。当前的区块链无法扩展以处理需要大量存储的应用,例如交易市场和社交应用。

所以 Sui Move 中没有全局存储。Sui Move 中不允许进行任何与全局存储相关的操作。(我们有一个字节码验证器来检测违规行为。)相反,存储只发生在 Sui 内。当我们发布一个模块时,新发布的模块存储在 Sui 存储中,而不是 Move 存储中。同样,新创建的对象存储在 Sui 存储中。这也意味着当我们需要在 Move 中读取一个对象时,我们不能依赖全局存储操作,而是 Sui 必须明确地将所有需要访问的对象传递给 Move。

地址代表对象 ID

Move 中有一种特殊的地址类型。此类型用于表示 Core Move 中的地址。Core Move 在处理全局存储时需要知道一个账户的地址。地址类型为 16 字节,这对于 Core Move 安全模型来说已经足够了。

在 Sui 中,由于 Move 不支持全局存储,因此我们不需要地址类型来表示用户账户。相反,我们使用地址类型来表示对象 ID。请参考 Sui 框架中的 object.move 文件来了解地址的使用。

对象具有 key 能力和全局唯一 ID

我们需要一种方法来区分 Move 内部的对象和可以跨越 Move-Sui 边界的对象(即可以存储在 Sui 存储中的对象)。这很重要,因为我们需要能够序列化/反序列化 Move-Sui 边界中的对象,并且此过程对对象的形状做出假设。

我们利用 Move 中的 key 能力来注释 Sui 对象。在 Core Move 中,key 能力用于告诉该类型可以用作全局存储的 key。由于我们在 Sui Move 中不涉及全局存储,因此我们可以重新利用此功能。我们要求任何具有 key 能力的结构都必须以具有 ID 类型的 id 字段开头。ID 类型包含 ObjectID 和序列号(又名版本)。我们有字节码验证器来确保 ID 字段是不可变的并且不能转移到其他对象(因为每个对象必须有一个唯一的 ID)。

模块初始器

正如 “以对象为中心的全局存储” 中所述,Move 模块是发布到 Sui 存储中的。一个可选地定义在模块中的特殊初始化函数,在模块发布时由 Sui 运行时执行(一次),目的是预初始化模块特定的数据(例如,创建单例对象)。初始化函数必须具有以下属性才能在发布时执行:

●命名 init
●&mut TxContext 类型的单参数
●没有返回值
●Privat

入口点将对象引用作为 input

Sui 提供了可以直接从 Sui 调用的入口函数,以及可从其他函数调用的函数。请参阅 Entry functions。

结论

总之,Sui 充分利用了 Move 的安全性和灵活性,并通过上述功能对其进行了增强,从而极大地提高了吞吐量,减少了最终确定的延迟,并让 Move 编程更容易。

原文:
https://docs.sui.io/learn/why-move
https://docs.sui.io/learn/sui-move-diffs
翻译:
Suiverse