深入研究 Move - Facebook 的 Libra 区块链编程语言

接下来,我们将详细考虑 Move 语言的主要特征,以及它与另一种已经流行的智能合约语言 Solidity(在以太坊平台上)的主要区别是什么。 该材料基于对可用的在线 26 页白皮书的研究。

介绍

Move是一种可执行字节码语言,用于执行用户交易和智能合约。 请注意两点:

  1. Move是一种可以直接在Move虚拟机上执行的字节码语言,而Solidity(以太坊的智能合约语言)是一种高级语言,在EVM(以太坊虚拟机)上执行之前先编译成字节码。
  2. Move 不仅可以用于实现智能合约,还可以用于自定义交易(稍后会详细介绍),而 Solidity 是一种仅限智能合约的语言。


翻译由 INDEX Protocol 项目团队进行。 我们已经翻译了 描述 Libra 项目的大型材料,现在是时候更详细地了解 Move 语言了。 与 Habrauser 联合进行翻译 酷秀

Move 的一个关键功能是能够使用基于线性逻辑的语义定义自定义资源类型:资源永远不能被复制或隐式删除,只能移动。 从功能上来说,这与 Rust 语言的功能类似。 Rust 中的值一次只能分配给一个名称。 将值分配给不同的名称会使其在以前的名称下不可用。

深入研究 Move - Facebook 的 Libra 区块链编程语言

例如,以下代码片段将引发错误: 使用移动值“x”。 这是因为 Rust 中没有垃圾收集。 当变量超出范围时,它们引用的内存也会被释放。 简单地说,数据只能有一个“所有者”。 在这个例子中 x 是原始所有者,然后 y 成为新的所有者。 在这里阅读有关此行为的更多信息.

开放系统中数字资产的表示

实物资产有两个难以用数字表示的属性:

  • 稀有 (稀缺,原本是稀缺的)。 必须控制系统中资产(排放)的数量。 必须禁止复制现有资产,创建新资产是一项特权操作。
  • 访问控制... 系统参与者必须能够使用访问控制策略来保护资产。

这两个特性对于物理资产来说是很自然的,如果我们想将它们视为资产,就必须为数字对象实现。 例如,一种稀有金属具有天然稀缺性,只有您可以使用它(例如,将其握在手中)并且您可以出售或花费它。

为了说明我们是如何得出这两个属性的,让我们从以下句子开始:

建议 #1:没有稀缺性和访问控制的最简单规则

深入研究 Move - Facebook 的 Libra 区块链编程语言

  • G [K]: = n 表示对可通过密钥访问的数字的更新 К 在区块链的全局状态下,具有新的意义 n.
  • 交易⟨爱丽丝,100⟩ 意味着将 Alice 的账户余额设置为 100。

上述解决方案有几个主要问题:

  • 爱丽丝可以通过简单地发送无限数量的硬币 交易⟨爱丽丝,100⟩。
  • Alice 发送给 Bob 的硬币是无用的,因为 Bob 可以使用相同的技术向自己发送无限数量的硬币。

建议#2:考虑赤字

深入研究 Move - Facebook 的 Libra 区块链编程语言

现在我们正在监控情况,以便硬币数量 Ka 至少是平等的 n 转让交易前。 但是,虽然这解决了稀缺性问题,但没有关于谁可以发送Alice的硬币的信息(目前,任何人都可以这样做,主要是不要违反限制数量的规则)。

提案#3:结合稀缺性和访问控制

深入研究 Move - Facebook 的 Libra 区块链编程语言

我们用数字签名机制解决了这个问题 验证签名 在检查余额之前,这意味着 Alice 使用她的私钥来签署交易并确认她是她的硬币的所有者。

区块链编程语言

现有的区块链语言面临以下问题(都在Move中解决了(注: 不幸的是,这篇文章的作者在他的比较中只对以太坊有吸引力,因此仅在这种情况下才值得考虑。 例如,以下大部分内容也在 EOS 中得到解决。)):

资产的间接代表。 资产使用整数进行编码,但整数与资产不同。 事实上,没有代表比特币/以太币/<任何硬币>的类型或值! 这使得编写使用资源的程序变得困难且容易出错。 诸如将资产传递给过程或从过程传递资产或将资产存储在结构中之类的模式需要语言的特殊支持。

赤字不可扩大... 语言只是一种稀缺资产。 此外,针对稀缺性的补救措施直接嵌入到语言本身的语义中。 开发者如果要创建自定义资产,必须自己仔细控制资源的各个方面。 这些正是以太坊智能合约的问题。

用户发行他们的资产 ERC-20 代币,使用整数来确定价值和总供应量。 每当创建新代币时,智能合约代码必须独立验证是否符合排放规则。 此外,在某些情况下,资产的间接列报会导致严重错误——重复、双重支出甚至资产完全损失。

缺乏灵活的访问控制... 目前使用的唯一访问控制策略是使用非对称加密的签名方案。 与稀缺性保护一样,访问控制策略深深嵌入语言的语义中。 但是如何扩展语言以允许程序员定义自己的访问控制策略通常是一项非常棘手的任务。

在以太坊上也是如此,其中智能合约不具备用于访问控制的本机加密支持。 开发人员必须手动设置访问控制,例如使用 onlyOwner 修饰符。

尽管我是以太坊的忠实粉丝,但我认为出于安全目的,资产属性应该由该语言原生支持。 特别是,将以太币转移到智能合约涉及动态调度,这引入了一种新的错误,称为重入漏洞。 这里的动态调度意味着代码的执行逻辑将在运行时(动态)而不是编译时(静态)确定。

因此,在 Solidity 中,当合约 A 调用合约 B 中的函数时,合约 B 可能会运行合约 A 开发者不希望的代码,这可能会导致 再入漏洞 (在账户余额实际扣除之前,合约A意外充当合约B提款)。

Move 语言设计基础知识

一阶资源

在较高的层次上,Move 语言中模块/资源/过程之间的交互与 OOP 语言中类/对象和方法之间的关系非常相似。
移动模块类似于其他区块链中的智能合约。 该模块声明了定义创建、销毁和更新声明资源的规则的资源类型和过程。 但所有这些都只是约定俗成(“行话”)在移动中。 稍后我们将说明这一点。

灵活性

Move 通过脚本编写为 Libra 增加了灵活性。 Libra 中的每笔交易都包含一个脚本,它本质上是交易的核心流程。 该脚本可以执行一个指定的操作(例如,向指定的收件人列表付款),也可以重用其他资源 - 例如,通过调用指定一般逻辑的过程。 这就是 Move 事务脚本提供更大灵活性的原因。 脚本可以使用一次性行为和重复行为,而以太坊只能执行可重复脚本(在智能合约方法上调用一种方法)。 之所以被称为“可重用”,是因为智能合约的功能可以被多次执行。 (笔记: 这里的要点非常微妙。 一方面,比特币中也存在伪字节码形式的交易脚本。 另一方面,据我了解,Move 实际上将这种语言扩展至成熟的智能合约语言的水平).

安全

Move可执行格式是字节码,一方面,字节码是比汇编语言高级的语言,但比源代码低级。 使用字节码验证器在运行时(链上)检查字节码的资源、类型和内存安全性,然后由解释器执行。 这种方式可以让Move提供源代码的安全性,但无需编译过程,也无需向系统添加编译器。 让 Move 成为一种字节码语言是一个非常好的解决方案。 它不需要像 Solidity 那样从源代码编译,也无需担心编译器基础设施可能出现的故障或攻击。

核查

我们的目标是尽可能简单地执行检查,因为所有这些都是在链上完成的(注意: 在线,在每笔交易的执行过程中,任何延迟都会导致整个网络的速度变慢),但是,最初语言设计已准备好使用链下静态验证工具。 虽然这是更可取的,但目前验证工具(作为单独的工具包)的开发已被推迟到未来,并且现在仅支持运行时(链上)的动态验证。

模块化

移动模块提供数据抽象和本地化资源的关键操作。 模块提供的封装与 Move 类型系统提供的保护相结合,确保模块类型上设置的属性不会被模块外的代码破坏。 这是一个相当深思熟虑的抽象设计,意味着合约内部的数据只能在合约框架内改变,而不能在合约框架外改变。

深入研究 Move - Facebook 的 Libra 区块链编程语言

移动概览

事务脚本示例表明,模块外部的程序员的恶意或粗心行为不会危及模块资源的安全性。 接下来,我们将查看如何使用模块、资源和过程来对 Libra 区块链进行编程的示例。

点对点支付

深入研究 Move - Facebook 的 Libra 区块链编程语言

金额中指定的硬币数量将从发送者的余额转移到接收者。
这里有一些新内容(以红色突出显示):

  • 0x0: 存放模块的账号地址
  • 货币: 模块名称
  • : 资源类型
  • 程序返回的币值是一个类型为 0x0.Currency.Coin 的资源值
  • 移动(): 值不能再次使用
  • 复制(): 值可以稍后使用

解析代码:第一步,发送方调用一个名为 撤回发件人 来自存储在的模块 0x0.货币。 第二步,发送方将资金转移给接收方,将币资源值移入模块的充值流程 0x0.货币.

以下是检查将拒绝的代码错误的三个示例:
通过更改调用来复制资金 移动(硬币)复制(硬币)。 资源只能移动。 尝试复制一定数量的资源(例如,通过调用 复制(硬币) 在上面的示例中)将在检查字节码时导致错误。

通过指定重新使用资金 移动(硬币) 两次 。 添加一行 0x0.Currency.deposit(复制(some_other_payee),移动(硬币)) 例如,上面将允许发送者“花费”硬币两次 - 第一次是与收款人,第二次是与收款人 其他收款人。 这是一种不良行为,对于有形资产来说是不可能发生的。 幸运的是,Move 会拒绝这个计划。

因拒绝而造成资金损失 移动(硬币)。 如果您不移动资源(例如,删除包含 移动(硬币)),会抛出字节码验证错误。 这可以保护 Move 程序员免受意外或恶意的资金损失。

货币模块

深入研究 Move - Facebook 的 Libra 区块链编程语言

每个账户可以包含0个或多个模块(显示为矩形)和一个或多个资源值(显示为圆柱体)。 例如,帐户位于 0x0 包含模块 0x0.货币 以及资源类型的值 0x0.货币.硬币。 账户地址 0x1 有两个资源和一个模块; 账户地址 0x2 有两个模块和一个资源值。

片刻:

  • 事务脚本是原子的——要么完全执行,要么根本不执行。
  • 模块是一段长期存在的代码,可以全局访问。
  • 全局状态被构造为哈希表,其中键是帐户地址
  • 帐户只能包含一个给定类型的资源值,并且不能包含多个具有给定名称的模块(帐户位于 0x0 不能包含额外的资源 0x0.货币.硬币 或另一个名为 货币)
  • 声明的模块的地址是类型的一部分(0x0.货币.硬币 и 0x1.货币.硬币 是不同的类型,不能互换使用)
  • 程序员可以通过定义其自定义资源在一个帐户中存储此类资源的多个实例 - (资源 TwoCoins {c1:0x0.Currency.Coin,c2:0x0.Currency.Coin})
  • 您可以通过名称引用资源而不会发生冲突,例如,您可以使用以下方式引用两个资源 两币.c1 и 两币.c2.

币种资源公告

深入研究 Move - Facebook 的 Libra 区块链编程语言
模块命名为 货币 和一个名为的资源类型

片刻:

  • 是一个具有一个类型字段的结构 u64 (64 位无符号整数)
  • 仅模块程序 货币 可以创建或销毁类型的值 .
  • 其他模块和脚本只能通过模块提供的公共过程写入或引用值字段。

出售存款

深入研究 Move - Facebook 的 Libra 区块链编程语言

此过程接受资源 作为输入并将其与资源相结合 存储在收件人的帐户中:

  1. 销毁输入资源Coin并记录其价值。
  2. 接收存储在接收者帐户中的唯一硬币资源的链接。
  3. 通过调用过程时参数中传递的值来更改硬币数量的值。

片刻:

  • 拆包,借用全球 - 内置程序
  • 打开包装 这是删除 T 类型资源的唯一方法。该过程将资源作为输入,销毁它,并返回与资源字段关联的值。
  • 借全球 接受一个地址作为输入并返回对该地址发布(拥有)的 T 的唯一实例的引用
  • 硬币 这是资源的链接

实施withdraw_from_sender

深入研究 Move - Facebook 的 Libra 区块链编程语言

这个程序:

  1. 获取独特资源的链接 ,链接到发件人的帐户
  2. 降低资源的价值 通过链接支付指定金额
  3. 创建并返回新资源 更新后的余额。

片刻:

  • 存款 任何人都可能造成,但是 撤回发件人 只能访问呼叫帐户的硬币
  • 获取Txn发送者地址 如同 消息发送者 坚固性
  • 拒绝除非 如同 要求 在坚固性中。 如果此检查失败,事务将停止并回滚所有更改。
  • 它也是一个创建 T 类型新资源的内置过程。
  • 打开包装, 只能在描述资源的模块内部调用 T

结论

我们研究了 Move 语言的主要特征,将其与以太坊进行了比较,并熟悉了脚本的基本语法。 最后,我强烈建议您查看 原始白皮书。 它包含许多有关编程语言设计原理的详细信息,以及许多有用的链接。

来源: habr.com

添加评论