To the Move: 面向资产编程的最佳语言

前沿

近期,随着 Aptos,Sui 等新公链的兴起,Move 作为这些公链新贵们的集体选择也随之受到了开发者和投资者的热捧。那么作为号称时薪1200刀的 Move 到底有何魅力呢?自带脸书光环?资本炒作还是实至名归?笔者试图从技术角度,从语言的设计的视角来谈谈我的看法。

先说结论,个人很认可Move的理念:资源作为一等公民(First-class Resources) 这个理念和区块链非常契合。区块链作为 Web3.0 的基础设施,承载了极客们对未来价值互联网的美好想象。当前的区块链应用无论是 DeFi,NFT 还是 GameFi 领域都是围绕数字资产来展开的,那么 Move 高举 资源作为一等公民 的大旗,原生的资产安全机制,恰好和价值互联网应用的需求完全契合,是面向价值,面向资产编程的最佳之选。


资料来源:https://medium.com/@kklas/smart-contract-development-move-vs-rust-4d8f84754a8f

说一点题外话,Move 的历史其实还挺曲折的,Move 最初在 2019 年是和 Libra 区块链共同被提出来的,创始团队来自 Facebook。彼时的 Libra 最初的目标是构建全球的货币和金融基础设施,Move 就被设计成 Libra 之上支持金融资产编程的语言。后来面临监管方面的压力,Libra 衍生到了2.0 增加了很多监管方面的机制,也改了名(Diem) 但是该区块链的发展却仍然不愠不火。直到最近,Diem 的创始团队纷纷出走,创立了 Aptos, Sui 等新兴公链被资本热捧,Move 的面向资产编程、高安全性、可验证、支持并行化等优势特性也再一次抓住大众的视野。

面向资产编程

资源作为一等公民是 Move 语言诞生之初就提出的设计理念。本文中所涉及的资源(或者资产)主要指的是数字化资产。根据 Move 白皮书引用的线性逻辑原理保障数字化资源也不可以被复制,不能被隐式丢弃,只能在程序的存储地址之间进行移动。

然而在开放的区块链环境中对数字资产进行编码存在两个难点:

  1. 稀缺性(Scarcity)表达:和信息互联网不同,单纯的数据本身是具有无限复制特性的、非排他性、无限供应的。价值互联网中的资产必须保持其独特性,资产的供应应该被严格控制,不可随意复制,新资产的创建也得在特权的许可下进行。
  2. 访问控制 (Access control)机制:区块链上的用户必须有能力来自己控制自己的数字资产,同时也应具备资产的访问权限配置的能力。

Move 语言是如何解决这两个难题的呢?

首先是资产建模,为了贯彻资源作为一等公民这个编程理念,Move 提出了一种特殊的结构体 即包含了 key 和 store 能力的结构体[1],称之为资源。

// 资源
struct Coin<T> has key, store {
  value: T,
}

// 普通结构体
struct Data {
 ...
}

这样就相当于语言底层原生支持资源这种特殊的数据结构,资源创建出来之后一定要在具体用户的地址下存储。

其次是资产一致性校验,资源的不可复制,不可随意增减,Move 设置了相应的规则来进行校验。如下图所示 Ka 和 Kb 分别标识两个账户,系统对于资产只能进行转移,并且需要保障整体的资产不可以凭空多出来,系统中一个人的资产增加了,那么一定是有一个用户的资产减少了,这个很好理解。

最后是访问权限控制,上面的模型中解决了稀缺性的问题,但是没有解决资产的访问控制权的问题,因此 Move 对其原型做了进一步增强,增加了用户的签名验证的环节,这都是语言层面提供的支持。

其他的编程语言对资产的编程是怎么做的呢?笔者也对其做了个简单的对比,如下表所示:

整体而言对资产的编程最成熟的属于 Solidity 体系,Solidity 的资产编程语言层面上是灵活的,不受限制的,也可以说是项目方随意指定。在实际的实践中,Solidity 资产标识采用的其实是共识的方式,这以ERC20/721/1155等为人们熟知,资产的访问控制也有签名验证,函数修饰器等多种方式。Move 和 Solidity比较起来资产的编程更加原生,不需要经历长期的共识,天生具备资产表达、聚合和编程的能力。


主流合约语言的资产编程特性

安全性和可验证性

Move 的安全包括链上和链下两个部分,字节码验证器 (bytecode verifier)和形式化验证器(Move Prover) 对合约进行静态和动态的全方位分析。

动态验证

Move 语言在设计的过程中继承了很多 Rust 中的安全特性,因此 Move 程序的安全性是全面的,例如资源安全、类型安全以及内存安全等。Move 合约严格来说是带类型的字节码,这种字节码是介于高级程序语言和汇编层级的底层语言之间,使得 Move 语言的使用兼顾了编程的便捷性和源自底层的安全性。Move 合约在链上执行时通过 bytecode verifier 的运行时工具对其资源安全、类型安全和内存安全进行检查。

静态验证

由于 Move 合约逻辑除了对资源的操作之外还可能会包含业务逻辑的描述,如果所有的 Move 合约逻辑都通过 bytecode verifier 进行检查会过多消耗 gas 费用。为了解决这个问题,Move 团队在语言设计的过程中提供了一种链下的静态验证工具( 称之为 Move Prover ),而链上仅保留尽可能少的针对核心操作的校验。为了让静态检查成为可能,Move 语言在设计中进行了相应的约束:

  • 不支持动态分发:业务逻辑中的每个调用都是静态可确定,可分析的。这让验证分析工具的实现变得更加简单。
  • 有限可变性:Move 在数据可变性方面继承了 Rust 的实现方式,使得程序在运行过程中有且仅有一个可变引用,bytecode verifier 采用 borrow checking [2] 的机制来进行引用的安全性检查。除此之外,语言在 global storage 的存储方面采用的是树形结构,而非更加自由的图结构,帮助验证工具更好地进行数据写入的影响面检查。
  • 模块化:模块化这点和传统的编程语言区别不大,主要是对资源相关的关键操作以及数据进行了合理的封装,避免代码跨模块随意调用。模块化的设计方式也为静态分析工具提供了隔离的验证环境,尽可能屏蔽来自其他方面的影响。

所以,Move 是什么

我们在上文中花了很多的篇幅对 Move 的优势及核心的设计理念进行了分析,那么集合了面向资产编程、安全性和可验证性的 Move 语言最终的呈现到底是什么样的呢?如下图所示是 Move 语言设计的整体架构视图:


资料来源:https://www.diem.com/en-us/blog/why-build-move/
首先,Move 的源程序层面,也就是源代码层面 Move: = script + module 由交易脚本和模块所构成。其中脚本(script)指的是对模块的临时调用逻辑,可以由调用者自由设计,这种调用方式比起 Solidity 的调用方式要更加灵活;模块(module)是链上合约的逻辑封装,包含了对资源的描述以及对资源的操作方法,这有点类似于高级语言中的类(class)的概念,系统中提供了一些基础功能的模块称之为标准库。Move 的源代码通过 Move 编译器可以编译成可解释执行的字节码。

其次,为了保证 Move 程序的尽可能安全,Move 的开发者在链下提供了称之为 Move Prover 的形式化验证工具,形式化验证工具依据开发者提供的 Move 的字节码以及 SPEC [4]信息可以对源代码的程序的安全性进行一定程度上的验证。

最后,Move 程序的执行部分,这也称为 MoveVM, MoveVM 一般来说深度集成在某个区块链中用于对链上的 Move 的字节码进行解释执行。MoveVM 抽象上来讲又包含了解释器(Intepreter)、字节码验证器(bytecode verifier)和加载器(Loader)三个部分。

  • 解释器: 依据用户提交的交易执行脚本对指定智能合约(一段Move 字节码)进行解释执行;
  • 字节码验证器:在解释器的执行过程中对资源安全、类型安全以及内存安全进行运行时检查;
  • 加载器:用于合约执行过程中和外部存储(一般是区块链的世界状态)的数据读写服务,加载特定智能合约以及其涉及到的具体数据。

从整体架构上来看 Move 和 Solidity的工具链和调用的链路基本类似。主要的亮点还是其面向资源的合约编程的模型以及为了安全而更克制的语言特性设计和更丰富的安全保障机制。

最后,Move 吗

从前文分析中我们看到 Move 高举资源作为一等公民的大旗,将资产数字化编码所需要的稀缺性和访问控制内置于语言底层,同时克制的设计语法辅以形式化验证器 Move Prover 和运行时验证器 bytecode verfier 极大地提供了智能合约的安全保障。因此,笔者可以断言 Move 确实是一门非常适合面向数字资产编程的语言。除此之外,Move 的语言设计也给 Move 的字节码执行提供了可并行执行的可能性,这在 Aptos 和 Sui 的区块链设计中都有所体现。这为区块链整体性能的提升带来了新的可能,这是 Solidity 类智能合约语言所难以具备的能力。

那么 Move 现阶段而言是最佳的智能合约编程语言吗?目前来看也不尽然,Move 除了其设计上的特性之外其距离大规模的工程化使用仍然有一定的距离。这里笔者提几个待完善的方面:

  1. Move 的工具链尚不完善,尚缺乏类似 Hardhat, Truffle 等顺手的开发工具;
  2. Move 的合约规范尚未形成,相比之下 Solidity 的 ERC20, ERC721, ERC1155 等已经非常成熟,Move 在 Aptos 和 Sui 中的一些定制化特性也给面向多链或者全链的应用开发者带来麻烦;
  3. Move 的合约生态尚不完善,贸然进行 Move 的合约开发也会面临很多冷启动的问题。

但是,笔者认为这也仅仅是暂时的障碍,不影响 Move 长期发展,Aptos 和 Sui 具备了公链崛起的全部叙事要素:顶级的团队,顶流的基金,一流的技术等等。

当然,实践是检验真理的唯一标准(毕竟不少 Ethereum 的挑战者们已经湮没在历史的尘埃里),笔者在此也呼吁所有对区块链、对 Web3.0 对 Move 有信仰的弄潮儿们勇敢地 Move 起来,让资产可编程,让价值安全流动,链接成网,川流不息!

参考文档

  1. https://diem.github.io/move/abilities.html
  2. https://rustc-dev-guide.rust-lang.org/borrow_check.html
  3. https://www.diem.com/en-us/blog/why-build-move/
  4. https://learnblockchain.cn/article/3459
  5. https://medium.com/@kklas/smart-contract-development-move-vs-rust-4d8f84754a8f
  6. https://diem-developers-components.netlify.app/papers/diem-move-a-language-with-programmable-resources/2020-05-26.pdf
  7. https://www.chaincatcher.com/article/2078369