Facebook Move 语言设计目标

Libra 的使命是建立一个简单的全球货币和金融基础设施,赋惠于数十亿人。Move 语言旨在提供安全,可编程的基础。Move 本身必须能够体现 Libra 货币是在一个精确的,可理解的及可验证的规则下治理。从长远来看,Move 必须能为不同类型的资产及其业务逻辑提供一个完善的财务基础设施。

为了满足这些要求,我们设计了 Move,考虑了四个关键目标:面向资源、灵活性、安全性和可验证性。

面向资源 First-Class Resources

区块链系统中,用户可编写直接与数字资产交互的程序。正如我们讨论过的在2.2节中,数字资产与传统编程中那些布尔值、整数和字符串不同,它是具有自己特殊的特征。怎么在编程中优雅地体现数字资产呢?

Move 能够自定义资源类型,这是 Move 的关键特性,也是受到线性逻辑(Linear Logic,译注:线性逻辑表示,如果某个变量符合某种特定的“结构”,它就内含一种规则:必须且只能使用一次。该特性也是 Rust 语言特性,参考)的方法论所启发:资源永远不能被复制或隐式丢弃,只能在程序存储之间移动位置。这些安全保证由 Move 的类型系统静态强制执行。尽管如此特殊保护,资源还是程序的普通值 - 它们可以存储在数据结构中,作为参数传递给程序等等。面向资源是一个非常普遍的概念,程序员不仅可以安全地使用数字资产,还可以编写正确的业务逻辑用于包装资产和实施访问控制策略。

Libra 货币本身就是作为普通的 Move 资源来实现的,在该语言中没有特殊的地位。由于 Libra 货币是由受管理的真实资产[19],因此都必须经过创建的资源(例如,当现实中有资产进入 Libra 保护区时)、经过修改(例如,当数字资产所有权改变时)、销毁(例如,当数字资产背后的有形资产被出售)。Move 程序员可以通过模块保护关键操作的访问。Move 模块类似于其他区块链语言中的智能合约。一个模块声明了资源类型和方法,其中的代码就是说明创建资源或者修改、删除的规则是怎样的。模块可以调用其他模块,或者使用其他的类型。但是,模块必须执行的数据抽象 - 模块对内是透明的,对外是不透明的。此外,对资源类型T的关键操作只能在定义 T 的模块内执行。

灵活性

我们说 Libra 很灵活,其实就是说 Libra 的交易脚本 Move 很灵活。每个 Libra 交易都包含一笔交易脚本,实际上就是交易语言的 main 方法程序。交易脚本只有一个不过里面可以包含更复杂的 Move 自定义代码,甚至可以把区块链上的其他程序都导入进来进行本地的计算,也就是说,交易脚本不但可以写那些一次性的代码(例如对一组特定的人付费),还能够复用代码,调用那些已经封装好的方法。

而 Move 模块本身就体现了 Move 代码的灵活性,而且安全。总体看,Move 中的模块/资源/方法似乎和面向对象的编程中的类/对象/方法差不多,但是重要的区别在于——Move 模块可以声明多种资源类型(或零个资源类型),而且 Move 程序没有 self 或 this 的对象概念。Move 模块其实很像限制过的 ML 语言模块(译注:ML,Meta Language 是一个通用的函数式编程语言)。

安全性

对于不满足某些关键特性的程序,Move 肯定拒绝,例如资源安全,类型安全,和内存安全。我们怎么知道区块链上的每个程序是否满足安全特性呢?有两个选择:一、使用高阶语言进行约束;二、运行时用低阶的汇编进行无类型的检查。

Move 采用了折中的方法。 Move的可执行格式是一种字节码,比汇编高级,比源码低级(译注:类似 Java)。字节码检查器会对字节码里面的资源、类型和内存保护进行链式检查,然后交给字节码解释器( Bytecode Interpreter)直接运行。该做法使得 Move 既可以检查源码的安全性,又无须增加源码编译器的计算负担,否则执行交易的时候,计算成本很大。

可验证性 Verifiability

理想情况下,我们会对 Move 程序的每个安全属性进行检查,可以包括是链式的字节码分析或运行时检查。但不幸的是,那是理想的。因为考虑到计算成本上,还有协议复杂度的问题上,如果都要检查那么对于大多数的安全保障其实是不必的,我们必须仔细权衡,拿捏准确。

我们的方法是对关键安全属性执行尽可能多的轻量级链式检查,但 Move 语言会支持高级的、非链式的静态验证工具。相对于其他一般性的开发语言,Move 添加了几项特性(设计中),目的就是为了使大多数人更容易接受静态验证。

  • 没有动态调度(Dynamic dispatch)。可以静态确定每个呼叫站点的目标。这使得验证工具很容易准确地推断方法调用的结果,但是不需要执行复杂的调用图才能分析。
  • 有限的可变性(Limited mutability)。只有通过引用才能让 Move 变量可变。引用是个临时值,必须在交易脚本的上下文范围内创建和销毁。类似于 Rust 的“借用检查(borrow checking)”方案,Move 的字节码验证器保证了在任何时间点最多存在某个值的可变引用。除此之外语言保证了全局存储的数据结构始终是树而不是任意的图。This allows verification tools to modularize reasoning about the effects of a write operation(不会译).
  • 模块化。凡是 Move 的模块,都必须强制进行数据抽象,还要把关键的资源操作本地化。模块的封装本身就是一种带强制性的保护。Move 类型系统的信息就是模块的信息,保证了外界的代码不能入侵本模块。由模块启用的封装与强制执行的保护相结合Move类型系统确保为模块类型建立的属性不能被模块外部的代码侵犯。这种设计的目的在于,不依赖客户端就能单独地对重要的模块(特别是那些不确定量)进行详尽的功能检查。

综合利用以上几项 Move 的特性,检查就能准确有效多了。静态验证工具不但能够检查运行时故障(例如,整数溢出),而且还能修正程序业务错误(例如,在支付渠道中参与者最终可以声明锁定的资源)。

译自官方文档:Move: A Language With Programmable Resources

展开阅读全文

没有更多推荐了,返回首页