Move:Facebook Libra区块链的新编程语言
概述和动机
这是 Facebook Libra新编程语言Move的26页技术白皮书的演练 。作为一个以太坊开发者和区块链社区爱好者,我希望为每个对这种新语言感到好奇的人提供一份快速概述和论文的重点:)希望你会喜欢它,快乐学习
关于媒体的原始文章:http://bit.ly/2ISy4uA
抽象
Move是一种可执行的字节码语言,用于实现自定义事务和智能合约。
有两件事需要注意:
- 虽然Move是一种字节码语言,可以在Move的VM中直接执行,但Solidity(以太坊的智能合约语言)是一种更高级别的语言,需要在执行EVM(以太坊的虚拟机)之前编译成字节码。
- Move不仅可用于实现智能合约,还可用于自定义事务(本文稍后将对此进行说明),而Solidity仅适用于以太坊上的智能合约。
Move的关键特性是能够定义具有受线性逻辑启发的语义的自定义资源类型:资源永远不会被复制或隐式丢弃,只能在程序存储位置之间移动。
这是一个类似于Rust的功能。Rust中的值一次只能分配给一个名称。将值分配给其他名称会导致无法再使用以前的名称访问该值。例如,以下代码段将输出错误: Use of moved value ‘x’
。这是因为Rust没有垃圾回收。当变量超出范围时,它们引用的内存也会被释放。为简单起见,我们可以理解这一点, 因为一次只能有一个“所有者”的数据 。在此示例中,x是原始所有者,然后y成为所有者。
2.2在开放系统中编码数字资产
有两种物理资产属性难以在数字资产中编码:•稀缺性。应控制系统中的资产供应。应禁止复制现有资产,创建新资产应具有特权操作。•访问控制。系统中的参与者应该能够使用访问控制策略保护其资产。
它指出了数字资产需要实现的两个主要特征,这些特征被认为是有形资产的自然特征。例如,稀有金属自然 稀缺 ,只有您在花钱之前就可以获得账单的 访问权(所有权)。为了说明我们如何提出这两个属性,让我们从以下提议开始:
提案#1:最简单的规则,没有稀缺性和访问控制
G[K]:=n
表示使用值updating更新存储在全局区块链状态中的密钥?处的数字。transaction ⟨Alice, 100⟩
意味着将Alice的帐户余额设置为100.上述表示存在严重问题:- 爱丽丝可以通过
transaction ⟨Alice, 100⟩
自己发送无限量的硬币。 - 爱丽丝发送给鲍勃的硬币毫无价值,因为鲍勃可以使用相同的技术向自己发送无限量的硬币。
提案#2:考虑到稀缺性
现在我们强制执行在转移之前存储在??下的硬币数量至少为?。然而,虽然这解决了稀缺问题,但是没有所有权检查谁可以发送爱丽丝的硬币。(任何人都可以根据此评估规则这样做)
建议#3:同时考虑稀缺性和访问控制
我们通过verify_sig
在稀缺性检查之前使用数字签名机制来解决问题 ,这意味着Alice使用她的私钥来签署交易并证明她是她的硬币的所有者。
2.3。现有的区块链语言
现有的区块链语言面临以下问题(所有这些都已在Move中解决 ):
- 间接代表资产。资产使用整数进行编码,但整数值与资产不同。事实上,没有任何类型或价值代表比特币/以太/稻草币这使得编写使用资产的程序变得笨拙且容易出错。诸如将资产传入/传出过程或将资产存储在数据结构中等模式需要特殊的语言支持。
- 稀缺性是不可扩展的。这种语言只代表一种稀缺资产。此外,稀缺性保护直接在语言语义中进行硬编码。希望创建自定义资产的程序员必须在没有语言支持的情况下仔细重新实现稀缺性。
这些正是以太坊智能合约中的问题。ERC-20令牌等自定义资产使用整数来表示其值和总供应量。每当新的令牌被铸造时,智能合约代码必须手动检查是否已达到稀缺性(在这种情况下为总供应量)。此外, 由于资产问题的间接表示,更有可能引入诸如重复,重用或资产损失等严重错误 。
- 访问控制不灵活。模型强制执行的唯一访问控制策略是基于公钥的签名方案。与稀缺性保护一样,访问控制策略深深嵌入语言语义中。如何扩展语言以允许程序员定义自定义访问控制策略并不明显。
在以太坊中也是如此,智能合约对公钥 – 私钥密码术没有本地语言支持来进行访问控制。开发人员必须手动编写访问控制,例如使用 OnlyOwner 。尽管我是以太坊的忠实粉丝,但我同意这些资产属性应该由语言本身支持以达到安全目的。
特别是,将以太坊转移到智能合约涉及动态调度,这导致了一类新的错误,称为重新入侵漏洞
这里的动态调度意味着代码执行逻辑将在运行时(动态)而不是编译时(静态)确定。因此,在Solidity中,当合约A调用合约B的功能时,合约B可以运行合约A的设计者未预料到的代码,这可能导致 重新入侵的漏洞 (合约A意外执行合约B的功能,以便在实际扣除余额之前提取资金。帐户)。
3.移动设计目标
3.1。一流的资源
在高层次上,Move中的模块/资源/过程之间的关系类似于面向对象编程中的类/对象/方法之间的关系。移动模块类似于其他区块链语言中的智能合约。模块声明资源类型和过程,这些资源类型和过程编码用于创建,销毁和更新其声明的资源的规则。
该 模块/资源/程序 只是在一些行话 移动。 我们将在本文后面有一个例子来说明这些;)
3.2。灵活性
Move通过事务脚本为Libra增加了灵活性。每个Libra事务都包含一个事务脚本,它实际上是事务的主要过程。
脚本可以执行富有表现力的一次性行为(例如支付一组特定的收件人)或可重用的行为(通过调用封装可重用逻辑的单个过程)
从上面我们可以看出, Move 的事务脚本引入了更多的灵活性,因为它能够 实现一次性行为 以及 可重用行为, 而以太坊只能执行 可重用行为 (这是一种调用单一智能合约方法)。它被命名为“ 可重用 ” 的原因 是智能合约功能可以多次执行。
3.3。安全
Move的可执行格式是一种类型化的字节码,它比汇编语言更高级但比源语言更低级。字节码通过字节码验证器在链上检查资源,类型和存储器安全性,然后由字节码解释器直接执行。此选项允许Move提供通常与源语言相关联的安全保证,但不将源编译器添加到可信计算库或编译到事务执行的关键路径的成本。
对于Move来说 ,这确实是一种非常简洁的设计, 它是一种字节码语言。由于它不需要从源代码编译为类似Solidity的字节码,因此不必担心编译器中可能出现的故障或攻击。
3.4。可验证
我们的方法是尽可能多地执行关键安全属性的轻量级链式验证,但设计Move语言以支持高级离线静态验证工具。
从这里我们可以看到Move更喜欢执行静态验证而不是进行链上验证工作。尽管如此,正如他们在论文末尾所述,验证工具留待将来工作。
- 模块化。移动模块强制执行数据抽象并本地化资源上的关键操作。模块启用的封装与Move类型系统强制执行的保护相结合,可确保模块外部的代码不会违反为模块类型建立的属性。
这也是一个非常好的数据抽象设计这意味着智能合约中的数据只能在合约范围内修改,而不能在外部修改。
4.移动概述
示例事务脚本演示模块外部的恶意或粗心程序员不能违反模块资源的关键安全不变量。
本节将向您介绍 编写编程语言时实际使用的模块,资源和过程的示例 。
4.1。点对点付款交易脚本
这里有几个新符号(小红色文字是我自己的笔记XD):
0x0
:存储模块的帐户地址Currency
:模块的名称Coin
:资源类型- 过程
coin
返回的值是类型为的资源值0x0.Currency.Coin
move()
:该值不能再次使用copy()
:该值可以在以后使用
代码细分:
在第一步中,发送方从存储在0x0.Currency的模块中调用名为withdraw from sender 的过程。
在第二步中,发送者通过将硬币资源值移动到0x0.Currency模块的存款过程中将资金转移到收款人。
以下是将被拒绝的3种代码示例:
1.通过改变来复制货币
move(coin)
至
copy(coin)
资源值只能移动。尝试复制资源值(例如,在上面的示例中使用复制(硬币))将导致字节码验证时出错。
因为 coin
是 资源 值,所以只能移动它。
2.通过写作重新使用货币
move(coin)
两次
添加行0x0.Currency.deposit(复制(一些其他收款人),移动(硬币))到上面的示例将让发件人“花”两次硬币 – 第一次与收款人,第二次与其他收款人。物理资产无法实现这种不良行为。幸运的是,Move将拒绝此计划。
通过忽视而损失货币
move(coin)
未能移动资源(例如,通过删除上面示例中包含移动(硬币)的行)将触发字节码验证错误。这可以保护Move程序员不会意外地或有意地丢失对资源的跟踪。
4.2。货币模块
4.2.1引物:移动执行模型
每个帐户可以包含零个或多个模块(描绘为矩形)和一个或多个资源值(描绘为圆柱体)。例如,地址0x0处的帐户包含模块0x0.Currency和类型为0x0.Currency.Coin的资源值。地址0x1的帐户有两个资源和一个模块; 地址0x2处的帐户有两个模块和一个资源值。
一些亮点:
- 执行事务脚本是全有或全无的
- 模块是在全球状态下发布的长期代码
- 全局状态的结构为从帐户地址到帐户的映射
- 帐户最多只能包含给定类型的一个资源值,并且最多只能包含一个具有给定名称的模块(地址中的帐户
0x0
不允许包含其他0x0.Currency.Coin
资源或另一个名为的模块Currency
) - 声明模块的地址是类型的一部分(
0x0.Currency.Coin
并且0x1.Currency.Coin
是不能互换使用的不同类型) - 程序员仍然可以通过定义自定义盘点器资源(
resource TwoCoins { c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin }
)来保存帐户中给定资源类型的多个实例 - 规则是可以的,只要您仍然可以通过其名称引用资源而不会发生冲突,例如,您可以使用
TwoCoins.c1
和引用这两个资源TwoCoins.c2
。
4.2.2声明硬币资源
一些亮点:
- Coin是一种结构类型,其单个字段值类型为u64(64位无符号整数)
- 只有程序中的
Currency
模块可以创建或破坏类型的值Coin
- 其他模块和交易脚本仅可以写或经由公共基准的值字段程序由暴露的模块
4.2.3实施存款
此过程将Coin资源作为输入,并将其与存储在收款人帐户中的Coin资源组合:1。销毁输入硬币并记录其值。获取对收款人帐户下存储的唯一Coin资源的引用。通过传递给程序的硬币值增加收款人硬币的价值。
一些亮点:
Unpack, BorrowGlobal
是内置的程序Unpack
删除类型为T的资源的唯一方法。它将类型为T的资源作为输入,销毁它,并返回绑定到资源字段的值BorrowGlobal
将地址作为输入并返回对该地址下发布的唯一T实例的引用&mut Coin
是Coin
资源的可变引用,而不是Coin
4.2.4实施撤回从发送方
这个程序:
- 获取对发件人帐户下发布的Coin类型的唯一资源的引用。通过输入量减少引用的Coin的值。创建并返回具有值金额的新硬币。
一些亮点:
Deposit
可由任何人调用,但withdraw_from_sender
具有访问控制只能由硬币所有者调用GetTxnSenderAddress
类似于Solidity的msg.sender
RejectUnless
类似于Solidity的require
。如果此检查失败,则当前事务脚本的执行将停止,并且它执行的任何操作都不会应用于全局状态Pack
,也是一个内置过程,创建一个T类型的新资源- 比如
Unpack
,Pack
只能在资源T的声明模块内调用
总结
现在您已经了解了Wave的主要特征 , 它与以太坊的比较,以及它的基本语法。最后,我强烈建议您阅读 原始白皮书 。它包含了许多关于编程语言设计原则的细节以及许多很好的参考资料。非常感谢你的阅读时间。随意与可能感兴趣的人分享这个:)欢迎任何建议
原文:https://kauri.io/article/aaff5b1d82dd46b9a8668ec983a71548/v2/whitepaper-deep-dive-move:-facebook-libra-blockchain’s-new-programming-language
作者:李婷婷
李婷婷現任圖靈鏈公司技術長與共同創辦人,和加州柏克萊大學區塊鏈研究院受邀學者。曾於微軟亞太區人工智能部門擔任顧問,同時亦於權威論壇ACM、IEEE及國際期刊 CPE 發表過三篇區塊鏈論文,並於德國慕尼黑CryBlock獲頒2018最佳論文。此外,也是知名Medium專欄作者筆括加密货币貨幣與區塊鏈,吸引全球逾3000位訂閱者,並於近期開設中文區塊鏈線上課程。興趣是擔任少女寫真外拍模特🙂