最近被 Libra 刷了屏。好多人都在谈论 Libra 对未来的影响,有从正面讨论的,认为会影响未来的数字经济,也有负面的,说我们还是逃不过被各大财阀控制的悲剧;有说 Facebook 在推动世界进步的,也有说小扎阴谋论的。这篇文章里,我们就不谈这些了,作为一名Developer,我们聊聊 Libra 附带推出的 Move 这门语言好了。
过去好像“无所不能”
作为一名区块链“从业者”,自从业以来,总有一种感觉————区块链这个新兴的技术,在写代码的时候能做的事情太多了。这并不是一种夸赞。我一直觉得总有一天区块链的世界里应该也会出现“编程范式”一样的东西来限制大家能做什么,不能做什么。
先来看几个例子:
基于以太坊的智能合约
Solidity 让你可以做很多事情,比如去年我尝试写一个颁发 Token 的智能合约。简单的实现了我自己期待的 Issue,Transfer,Destroy 方法,就可以了。
当然,假如你知道 OpenZeppelin 的话,把它引到代码库中,然后实现它里面的 ERC-20 就更完美了。
可是问题在于,它赋予了你选择的权利,你可以用也可以不用,那么你完全可以随意写一个 Token 然后部署到 Production 上,然后就会遇到各种奇奇怪怪的问题。比如:
- 双花问题: 客户的 Token 可以被花两次。
- 重入攻击: 以太坊 “DAO” 项目遇到的问题,黑客可以利用这个 Bug 无限的向自己的账户中转账,直到合约的余额为 0。
问题在于,以太坊让我可以很自由的去做很多事情,定义很多事情。
基于 Corda 的智能合约
从去年就开始在一个用 Corda 的项目上,从开始接触 Corda 到后来使用 Kotlin 写 Corda 的智能合约,就一直有一个苦恼,要写的 Corda 的逻辑几乎超过了业务逻辑。
我们消耗了大量的时间去处理,交易发起方应该找谁索要签名;作为交易接收方要如何处理,等一系列诸如此类的问题。
我们暂且抛开 Corda 的自身原因不谈,但是我一直纳闷,为什么想要专心写业务逻辑这么麻烦,为什么要把业务逻辑和这些区块链的业务混在一起呢?
问题在于,Corda 给我的灵活度更高,可是随之而来的风险也就越多。
从上面来看,我们会发现,区块链作为一个新兴的技术赋予了 Developer 太多的能力,而这些能力是没有过多的限制的,以太坊不会限制我的资产要怎么交易,因为我的资产在以太坊上只是智能合约里面的数据而已;Corda 不会限制我找谁签名或者做什么验证,因为 Corda 是把这些权利放给了 Developer 的。
可是,有时候没有限制,并不是一件好事。就像“编程范式”一样,我一直在想,是不是有一天,区块链也会出现自己的“编程范式”,规定 Developer 能做什么,不能做什么。比如规定作为一个资产,它是不能被复制,不能被随意销毁的。
过去,区块链世界里的合约仿佛无所不能,没有节制。那么未来,也许需要变一变了吧。
“他”从何处来
Libra 出的第一天在一个微信群里面看到有人问,“我就不理解为什么每个人需要创造一种新语言。”
在 Move: A Language With Programmable Resources 中可以找到答案,文章指出,现实世界中的资产数字化过程中面临着两方面的困难——稀缺性 和 权限控制。而现有的平台,如以太坊、比特币等也同样面临着几个问题:
- 资产的不正规表示(Indirect representation of assets)
- 自定义资产稀缺性描述,在区块链编程语言中得不到良好的支持(Scarcity is not extensible)
- 权限控制功能深植于语言之中,难以自定义(Access control is not flexible)
单从 Solidity 的开发而言,上面提出的三个问题确实是存在的,在 Solidity 中如上文提到的,如果想要自己发布 Token,其本质是合约决定的,其中的 Balance 多数是用 Integer 表示,而其表意性太差;其次,由于 Token 自己颁发,几乎所有的内容都需要自己在合约中写出来,合约中的内容都是由合约所有者维护的,包括其本质的问题:稀缺性和权限控制。一旦出现问题,那么对于这个 Token 而言将是灾难性的。
事实上,当前区块链平台所使用的编程语言存在的普遍问题在于,他们几乎和过往的编程语言没有过多的区别。可是我们应该意识到的是,区块链与我们传统的平台开发是不同的。传统的平台开发基于的是大家具有不同的业务逻辑与基础内容,本质上大家所处理的内容几乎完全不同。
以 Salesforce 为例,Salesforce 内部使用的 Apex 语言本身操作的是一个个类似于 pse__XXXX__c 的 Customer Class,每个 Class 具有的属性和自身情况不同。
而区块链本身操作的是资产(Asset),资产本身的特性是所有被称为资产的 Class 所共有的逻辑,所以其应该作为一种基本的资源向开发者提供而不是作为一种可供选择的资源。以此为据,我们可以姑且认为,在区块链的世界中基础的资产类型应当是开发者认为的底层,而不是业务逻辑。因此支撑区块链平台的语言要比以前的编程语言在基础上多了一层对于基础类型的封装 — 即对资产类型的保护。
而 Move 本身的设计目标就是 -- 资产是一等公民(First-class assets)、灵活性(Flexibility)、安全性(Safety)、可验证性(Verifiability)
从语义上将资产(Asset)作为其支持的一部分,而不是由用户自定义其基础(稀缺性、权限控制)的实现逻辑。用户只需要自定义自己需要实现的部分即可,如:转账逻辑、退款逻辑等等。更加聚焦于业务而非底层。
“他”的特点
From 30,000ft — Move 中的两大类型
These safety guarantees are enforced statically by Move’s type system.
-- Move: A Language With Programmable Resources
从上帝视角来看,Move 把其中的类型分成了两个大类:
- Unrestricted Value
- Resource
Unrestricted Value 是指那些如:u64 或者 钱包地址 一类的信息,可以被正常的复制和转移。
Resource 则是我们之前所说的资产(Asset),基于 Linear Logic,就如同货币一样,Resource 不能被复制,只能被转移,并且只能被转移一次;且不能被隐式丢弃。
From 20,000ft — Move 中的两个程序模型
Move 把代码分成了:
- Transaction script
- Modules
这两种不同类型的代码分别代表了两种不同的逻辑,根据 Move 的描述,Modules 接近我们认为的智能合约,在 Module 内部可以规定定义的内容的转移,销毁,发布等业务逻辑。
而 Transaction script 用来执行交易指令,比如,Alice 向 Bob 转 100 Libra,这个操作就是 Transaction script,而 100 Libra 和转移过程中要经历怎样的逻辑则是 Modules 的职责了。
事实上,Transaction script 具有 all or nothing 的特性,即要么都成功,要么都失败,不会存在一种中间状态。举一个 terraform 的例子,虽然不恰当,但却是 all or nothing 的反例,在 terraform 中,如果你定义的某个 instance 创建失败了,虽然结果中会提醒你命令失败,但实际上其他的 instance 都会被创建成功。
在区块链网络中如果也出现同样的状况,那就很可怕了。假如 Alice 转账给 Bob 100 Libra,假设在转账过程中,我们的逻辑是先转账,后计算 Alice 的余额,在转账成功后,操作失败了。那么就会出现 Alice 的余额没有减少,Bob 收到了 100 Libra。而这会对区块链网络造成毁灭性的打击。
值得注意的是,尽管 Libra 中允许实现各自的资产作为一种 Resource,但是,Coin 和 Coin 之间是互不相通的。
0x0.Currency.Coin and 0x1.Currency.Coin are distinct types that cannot be used interchangeably.
-- Move: A Language With Programmable Resources
所以未来可能会有类似交易银行一样的 module 出现来帮助自定义 Coin 之间进行转化。
落到地上 — Move 源码
Move intermediate representation(Move IR)是由 Rust 写成的,因此,可以将 Move IR 看作是 Rust 写成的 DSL 语言。
在使用 cargo 构建项目上时,其实是将*.mvir
文件作为 String 传入 Rust 编译器中,由 Parser 转为 Rust 代码运行的。因此,在大家想要深入了解 Move 的本质时,可以通过 parser/
目录中的 ast.rs
详细了解 Move 语言的关键字与数据结构;也可以通过 syntax.lalrpop
对 Move 的语法结构有一个基本的了解,其中定义了包括诸如:AccountAddress,StructType,IfStatement,LoopStatement 等内容。
如果希望能够通过测试来了解更多关于 Move 的用法,可以通过 language/funcational_tests/payments/
文件夹下的代码来了解一些基本的转账操作。
“他”向何处去
In the longer term, Move must be capable of encoding the rich variety of assets and corresponding business logic that make up a financial infrastructure.
-- Move: A Language With Programmable Resources
在文章中,特意有一个第七小节名为”What’s Next for Move“足见 Libra 对于 Move 的期待和规划。尽管上文我们提到了 Move 为了解决的问题,以及它的主要目标 -- 竞争优势。但其实如果去看 Move 的源码,你会发现它其实远没有到成熟的程度。
作为一个新出的语言(我们前面提到,Move 其实是基于 Rust 写的 DSL 语言),尽管它基于 Rust 构建了自己强大的类型系统,保证资产(Asset)的稀缺性和权限控制。也构建了一套适用于 Libra 网络的编程模型。
代码
但就使用 Move 写代码而言,依然有很多不直观的地方。Move 借鉴了很多 Rust 相关的内容 — move,&mut,类型等。但是其本身在很多方面依然做的不够好。比如:
- 代码表意方面,代码中使用了大量的 Hard code 返回值状态码;Move 语言的测试例子中,很多 test case 起不到快速上手的帮助作用。
- 如上文提到的,Move 是一门基于 Rust 的 DSL 语言,在测试时产生的报错会变得不是那么友好:
所以就像文章中提到的:接下来的,Move 会:
- 逐步地实现 Libra 网络的核心功能(Implementing core Libra Blockchain functionality)
- 增加新的语言功能,如:Collection、Event(New Language features)
- 增强开发人员的开发体验(Improved developer experience)
- 正式规范与验证(Formal specification and verification)
值得注意的是:
- 在 “New Language features” 中的一句话: In addition, we will develop a trusted mechanism for versioning and updating Move modules, transaction scripts, and published resources。众所周知,区块链要不要做 CI/CD、怎么做 CI/CD 一直都是大问题。让我们拭目以待 Move 在这方面的设计吧。
- 在 “Formal specification and verification” 中: We will create a logical specification language and automated formal verification tool that leverage Move’s verification friendly design. 未来,Move 期待用户在未来能够构建一个正确性的文化,通过形式化证明的方式来理解一个 module 的功能。
生态
我们常常听人谈“生态”,生态之所以重要,在于生态的存在可以让一个语言在一个众人共同的思维体系下完善以及推陈出新。Move 显然十分认可“生态”的存在,因此,在长远发展的方向上,将支持第三方 Move module(Support third-party Move modules),放在了长期目标中。
Steps such as creating a marketplace for high assurance modules and providing effective tools for verifying Move code will help. 说明在 Move 看来,尽管生态重要,但是作为一个具有广大用户量的区块链平台,其本身应该还是在以不影响用户体验、以及不产生 Bug 的前提下进行,所以采用这种类似于“收取 Gas 手续费”、放在 Marketplace 的方式来增加作恶成本。
需要承认,Libra 依然处在一个高速发展的阶段,Move 也是如此,尽管从文章与代码中,我们看到了Move 对于区块链世界的郑重。看到了他们的决心。而 Move 会大有可为的,甚至可能会成为区块链的“编程范式”的一个良好的开始。
最佩服的是,他们就带着那样一股子一往无前的信念向前走去。不管他们的未来如何,反正他们已经改变了现在,而未来也终将因为他们的存在而变的不是那么一样。
这让我想起了:
大圣,此去欲何?”
“踏南天,碎凌霄。”
“若一去不回……”
“便一去不回!”
--《悟空传》
文/ThoughtWorks王瑞鹏
更多精彩洞见,请关注微信公众号:ThoughtWorks洞见