Facebook Move编程语言入门:易于开发吗?
Facebook区块链项目Libra的其中一个技术亮点,就是它使用了一种称为Move的新编程语言,那么这种语言是怎样的呢,今天我们就从其官方的概述资料入手,近距离了解这种新的语言。
以下内容为译文:
Move是一种新的编程语言,它为Libra区块链提供了一个安全和可编程的基础。Libra区块链中的账户是任意数量Move资源及Move模块的容器。提交至Libra 区块链的每个事务,都使用以 Move语言编写的事务脚本对其逻辑进行编码。
这个事务脚本可调用模块声明的过程来更新区块链的全局状态。
在本指南的第一部分内容中,我们将概括性地介绍Move语言的主要特点:
对于求知欲强的读者来说,Move编程语言的技术论文包含了更多关于该语言的细节信息:
在本指南的第二部分,我们将向你展示如何在Move中间代码优化(IR)的环境下编写自己的应用。初始的测试网并不支持自定义Move程序,但这些功能可供你在本地试用。
(图片来自:libra.org)
1、1 Move事务脚本启用可编程事务
1、2 Move 模块允许组合型智能合约
Move模块定义了更新Libra区块链全局状态的规则。Move模块与其它区块链中的智能合约一样都是解决相同的问题。模块声明了可在用户账户下发布的资源类型。Libra区块链中的每个账户都是任意数量资源和模块的容器。
1、3 Move语言具有第一类资源
2、1 Move中间代码优化(IR)
本节介绍如何使用Move IR 编写事务脚本以及模块。先提醒下读者,这个Move IR 目前还处于早期的阶段,因此并不稳定,它也是接下来会介绍的Move 源语言的前身(有关详细信息,请参阅未来开发者体验部分内容)。Move IR是在Move bytecode之上的一个很薄的语法层,用于测试bytecode验证者以及虚拟机,它对开发者而言不是特别友好。Move IR足以用于编写人类可读的代码,但无法直接转换为Move bytecode。尽管Move IR还是有些粗糙,我们还是对这个Move语言感到兴奋,并希望开发者们可以尝试一下它。
我们会介绍关于Move IR的重要演示代码段,并鼓励读者通过在本地编译、运行和修改示例来了解它。以及的说明文件解释了如何执行此操作。
2、2 编写事务脚本
正如我们在Move事务脚本启用可编程事务部分内容中所解释的,用户编写事务脚本,以请求对Libra区块链的全局存储进行更新。几乎任何事务脚本中都会出现两个重要的构建块:和资源类型,是模块的名称,是该模块声明的资源的名称。这是在Move中常见的命名规则。模块声明的“main”类型通常命名为T.
当我们说一个用户“在Libra区块链上拥有一个地址为的帐户”时,我们的意思是,这个地址持有资源的实例。每个非空地址都有一个资源。此资源存储账户数据,如序列号、验证密钥和余额。要与帐户交互的Libra系统的任何部分,都必须通过从资源中读取数据或调用模块的过程。
账户余额是的一种类型资源。正如我们在Move具有第一类资源部分内容中解释的,这是Libra币的一种类型。这种类型是语言中的“第一类公民”,就像其他Move资源一样。的类型的资源可以存储在过程变量中,在过程之间传递,等等。
我们鼓励感兴趣的读者在目录下检查和模块中这两个关键资源的Move IR定义,
现在,让我们看看程序员如何在一个事务脚本中与这些模块和资源交互。
此事务脚本存在着一个不幸的问题:如果地址接收方没有账户,它将失败。我们将通过修改脚本来解决这个问题,为接收方创建一个账户(如果接收方还不具备账户的话)。
让我们看一个更复杂的例子。在这个例子中,我们将使用事务脚本为多个接收方进行支付(而不是单个接收方)。
// Multiple payee example. This is written in a slightly verbose way to // emphasize the ability to split a `LibraCoin.T` resource. The more concise // way would be to use multiple calls to `LibraAccount.withdraw_from_sender`.
import 0x0.LibraAccount; import 0x0.LibraCoin; main(payee1: address, amount1: u64, payee2: address, amount2: u64) { let coin1: R#LibraCoin.T; let coin2: R#LibraCoin.T; let total: u64;
total=move(amount1) copy(amount2); coin1=LibraAccount.withdraw_from_sender(move(total)); // This mutates `coin1`, which now has value `amount1`. // `coin2` has value `amount2`. coin2=LibraCoin.withdraw(&mut coin1, move(amount2));
// Perform the payments LibraAccount.deposit(move(payee1), move(coin1)); LibraAccount.deposit(move(payee2), move(coin2)); return; }
好了,到这里,我们就结束了事务脚本部分的展示,有关更多例子,包括初始测试网中支持的事务脚本,请参阅
libra/language/stdlib/transaction_scripts
2、3 编写模块
现在,我们把注意力集中到编写自己的Move模块上,而不仅仅是重用现有的和模块。考虑这样一个情况:Bob将来某个时候将在地址a创建一个帐户,Alice想要“指定”Bob一笔资金,以便他可以在账户创建后将其存入自己的帐户。但她也希望,如果Bob一直不创建一个账户,她就能收回这笔资金。
为了解决Alice的这个问题,我们将编写一个专用的模块,它会:
Alice可以为Bob创建一种预先安排的币,方法是创建一个事务脚本,调用Bob的地址a的,以及她所拥有的。一旦地址a被创建,Bob就可以通过从a发送一个事务来领取这笔币,这会调用,将结果传递给,并将返回的存储在他希望的任何地方。如果Bob在创建a的过程中花费的时间太长,而Alice想要收回她的资金,那么Alice可以使用,然后。
观察型读者可能已经注意到,本模块中的代码对的内部结构不可知。它可以很容易地使用泛型编程(例如,)编写。我们目前正致力于为Move增加这种参量多态性。
2、4 未来开发者体验
在不久的将来,Move IR将稳定下来,编译和验证程序将变得更加对用户友好。此外,IR源的位置信息将被跟踪,然后传递给验证者,以使错误消息更容易排错。然而,IR将继续作为测试Move bytecode的工具。它是作为底层bytecode的一种语义透明的表示。
为了允许有效的测试, IR编译器需生成错误的代码,这些代码将被bytecode验证者拒绝,或在编译器的运行时失败。
而对用户友好的源语言则是另一种选择,它应该拒绝编译在管道的后续步骤中将失败的代码。
未来,我们将拥有更高层次的Move源语言。这种源语言将被设计成安全而容易地表达常见的Move惯用语和编程模式。由于Move bytecode是一种新语言,而Libra区块链是一种新的编程环境,我们对应支持的习惯用法和模式的理解,仍在不断发展。目前,源语言还处于开发的早期阶段,我们还没有为它准备好发布时间表。