从比特币、以太坊、libra的不一样特色认识move语言

关于比特币、以太坊、libra,咱们知道他们是不一样的区块链应用,那么他们的根本差异在哪里呢。
其实,单从白皮书的标题,就能够大概看出三个项目在设计目标上的差别。程序员

  • 比特币的目标是 —— 可编程货币(Programmable Money),因此白皮书标题是 “Bitcoin: A peer-to-peer electronic cash system”。
  • 以太坊的目标是 —— 可编程的去中心化应用(Programmable dApps),在货币的基础上,扩展到更通用的领域。因此白皮书标题是:“Ethereum: a next generation smart contract and decentralized application platform”,黄皮书标题是:“Ethereum: A secure decentralized generalized transaction ledger”。
  • Libra 的设计目标刚好介于两者中间 —— 可编程资源(Programmable Resources),或者叫可编程资产。

那么,“可编程货币”、“可编程应用”、“可编程资源”,这三者到底有什么不一样呢?
既然都是 “可编程 XX” 句式,他们的主要区别就在于两点:
对什么编程;
如何编程。
对什么编程?编程

对什么编程,是指系统所描述或者抽象的,究竟是现实世界中的什么东西。安全

比特币对 “货币” 编程

比特币系统抽象的是 “货币”,或者说是 “帐本” 的概念。货币能够用一个数字来描述,也就是某一个帐户的 “余额”。用户能够经过 “交易”,把一部分钱转给别人。当比特币网络接收到一笔交易的时候,每一个节点都会检查交易是否合法,好比你花的是否是本身的钱,有没有足够的余额(比特币不容许透支)。当这些检查都成功后,节点会作一个简单的加减计算:在你的帐户中扣减转帐的数额,并在对方帐户中加上一样的数量。所以,比特币惟一的功能就是记帐,保证在帐户彼此转帐的过程当中,货币的总量不会莫名其妙的增长或减小(不考虑挖矿奖励和黑洞地址等特例)。网络

以太坊对 “应用” 编程

以太坊系统抽象的是 “应用”,应用的种类一应俱全,好比游戏、借贷系统、电商系统、交易所等,这些都是应用。理论上讲,任何传统的计算机程序均可以移植到以太坊上。所以,以太坊中记录的是各类应用的内部数据(即 “合约状态”),好比一个电商系统的库存、订单、结算信息等。这些信息没法用一个简单的数字来描述,必须容许用户定义很是复杂的数据结构,而且容许用户经过代码(智能合约),来对这些数据进行任意所需的操做。固然,这些应用也包含了 “货币帐本”。事实上,目前在以太坊上应用最普遍的正是此类应用(称为 “ERC20 智能合约”)。因为以太坊把这类应用看做是平台所能支持的多种应用中的一种,与其余类型的应用相比,并无什么特别之处,因此也就没有针对此类应用提供更多的安全保护,只提供了相似 ERC20 这样的接口规范。一个在以太坊上新发行的 “货币”,其转帐逻辑的正确性彻底由开发者负责。
在这里插入图片描述
在以太坊的存储结构中,ERC20代币 的帐本是 “二级对象”,和 ETH 原生代币余额存储在不一样的地方。例如上图所示,0x0,0x1 和 0x2 是三个以太坊地址,其中,0x0 和 0x2 是普通帐户地址(External accounts),而 0x1 是一个合约地址(Contract accounts)。咱们能够看到,每一个帐户都存储了一个 ETH 的余额,这个数据是顶级对象 (First-Class Object)。在合约地址 0x1 中,还存储了一个智能合约代码 MyCoin,它是一个 ERC20 代币应用。而 MyCoin 这个代币的整个帐本,都存储在 0x1 的空间中,怎么修改都由 0x1 中的合约代码说了算。数据结构

不管是有意仍是无心,ERC20代币 很是容易出现安全漏洞。也就是说,在以太坊系统中,原生代币 ETH 和用户发行的代币并不享有一样的安全级别。app

Libra 对 “资产” 编程

那么,可否不那么走极端,试图去抽象一些比简单数字更复杂的资产类型,而又不追求一应俱全的 “通用性” 呢?这正是 Libra 的出发点。Libra 能够定义相似一篮子货币、金融衍生品等比货币更复杂的资产类型,以及如何对他们进行操做,这种资产被称为 “资源”。Move 经过限制对资源的操做来防止不恰当的修改,从而提升资产的安全性。不管资源的操做逻辑如何,都必须知足两个约束条件:electron

  • 稀缺性。即资产总量必须受控,不容许用户随意复制资源。通俗的说,就是容许银行印钞,但不容许用户用复印机来 “制造” 新钱;
  • 权限控制。简单的说就是资源的操做必须知足某种预先定义的规则。例如,张三只能花本身的钱,而不容许花李四的钱。
    在这里插入图片描述
    上图是 Move 的世界状态,与以太坊不一样,它把全部资产都看成是 “一等公民”(First-Class Resources),不管是 Libra 的原生代币,仍是用户本身发行的资产。任何一个 “币种” 的余额,都存储在用户地址对应的空间中,对其进行操做受到严格的限制。这种被称为资源(resource)的对象,在交易中只能被移动,并且只能移动一次,既不能被复制,也不能被消毁。甚至严格到在代码中赋值给一个局部变量,然后面没有使用它也不容许。

这种资产的存储方式并不是 Libra 首创,在此前的一些公链中已有应用,例如在 Vite 公链中,用户发行的币种余额也是顶级对象。不过 Move 能够支持更为复杂的资产类型,并对其提供额外的保护,这是 Libra 的主要贡献。编程语言

编者组: Vite 是本文做者建立的项目。区块链

如何编程?

咱们再来看看三个项目如何经过编程来实现丰富的扩展性。ui

比特币脚本

在比特币中,定义了一种 “比特币脚本”,用来描述花一笔钱的规则。比特币是基于 UTXO 模型的,只有知足了预先定义的脚本规则,才能花费一笔 UTXO。经过比特币脚本,能够实现 “多重签名” 之类的复杂逻辑。比特币脚本是一种很是简单的基于栈的字节码,不支持循环之类的复杂结构,也不是图灵完备的。虽然利用它能够在比特币网络上发行新的货币(Colored Coins),但它的描述能力很是有限,对开发者也不友好,没法应用到更复杂的场景中。

以太坊的 Solidity 语言

在以太坊中,定义了一种 Solidity 的编程语言,能够用来开发 “智能合约”。智能合约代码能够编译成一种基于栈的字节码 ——EVM Code,在以太坊虚拟机 EVM 中执行。Solidity 是一种高级语言,参考了 C++、Python 和 Javascript 的语法,是一种静态类型、图灵完备的语言,支持继承,容许用户自定义复杂的类型。Solidity 更像是一种通用的编程语言,理论上能够用来开发任何类型的程序,它没有针对货币或者资产类型的数据,在语法和语义上作任何限制和保护。好比用它来开发一个新的代币合约,代币的余额一般声明为 uint 类型,若是编码时对余额增减逻辑的处理不够当心,就会使余额变量发生溢出,形成超额铸币、随意增发、下溢增持等严重错误, 如: BEC 智能合约的漏洞。

Libra 的 Move 语言

再来看 Libra,它定义了一种新的编程语言 Move,这种语言主要面向资产类数据,基于 Libra 所设定的 “顶级资源” 结构,主要设计目标是灵活性、安全性和可验证性。目前,Move 高级语言的语法设计尚未完成,白皮书只给出了 Move 的中间语言(Move IR)和 Move 字节码定义。所以咱们没法评估最终 Move 语言对开发者是否友好,但从 Move IR 的设计中,能够感觉到它在安全性和可验证性方面的特色。

Move 语言的设计

下面咱们来简单介绍一下 Move 的语法。Move 的基本封装单元是 “模块”(Module),模块有点相似于以太坊中的 “智能合约”,或者面向对象语言中的 “类”。模块中能够定义 “资源”(Resource)和 “过程”(Procedure),相似于类中的 “成员”(Member) 和 “方法”(Method)。

全部部署在 Libra 上的模块都是全局的,经过相似于 Java 中的包名 + 类名的方式来引用,例如 0x001.MyModule,0x001 是一个 Libra 地址,MyModule 是一个模块名。模块中的过程有 public 和 private 两种可见性,公有过程能够被其余模块调用,私有过程只能被同模块的过程调用。而模块中的资源都是私有的,只有经过公有过程才能被其余模块访问。并且,外部模块或者过程对本模块资源的修改受到严格的限制,惟一容许的操做就是 “移动”(Move),不能随意对资源赋值。例如,Move 中是不容许出现一个相似于 MyCoin.setBalance() 这样的接口,让其余用户有机会随意修改某个币种余额的。

除了受限的资源类型,Move 模块中也容许定义非受限的成员,被称为非受限类型(Unrestricted Type),包括原生类型(boolean、uint6四、address、bytes)和非资源类的结构体(struct)。这些非受限类型就没有那么严格的访问限制,能够用来描述与资产无关的其余应用类数据。从这个角度来讲,Move 语言理论上应该具备和 Solidity 一样的描述能力,但因为实际的去中心化应用中,总会涉及到资产类的数据,而任何引用了资源类型的结构体也都是受限的,可以真正脱离 Move 语言严格限制的机会并很少。因此在实际使用 Move 语言开发的时候,程序员必定会有一种戴着镣铐跳舞的感受,代码出现编译时和运行时失败的可能也更大。

通俗的说,用 Move 写代码不会让你感受 “很爽”,这就是安全性和可验证性的代价。想一想你用 C 语言本身控制内存的分配和释放时,虽然有一种 “我是上帝” 的感受,但也会时刻忧虑缓冲区溢出、内存泄露等潜在风险;而用 Java 语言开发,虽然你再也不可以随心所欲的控制内存,但也不用担忧这些内存安全性问题了。自由仍是安全,每每是不兼得的。

在一个 Libra 的交易(Transaction)中,也能够嵌入一段 Move 代码,被称为交易脚本(Transaction Script)。这段代码不属于任何模块,是一次性执行的,不能再被其余代码调用。脚本中能够包含多个过程,经过 main 过程做为入口来执行,在其中也能够调用其余模块中的过程。这个设计有点相似比特币,而和以太坊彻底不一样。在以太坊中,一个交易自己是不能包含一段可执行代码的,只能部署新合约或者调用一个已部署的合约。我不太喜欢 Libra 的这个设计,因为任何 Move 代码都必须通过字节码验证器(Bytecode Verifier)的严格检查才能发布到链上,这种一次性代码的边际成本远远高于可复用的模块,会拖慢交易被确认的速度,下降系统的吞吐量。交易脚本并非必须的,大部分现实场景均可以经过模块来覆盖,并且,它的存在还增长了 Libra 钱包的开发和使用难度,有机会的话我会向 Libra 的开发团队提议取消这一设计。

本文内容首发于深刻浅出区块链技术博客,点击解读 Libra Move:一种可编程资源语言看一下白皮书中的示例代码片断,直观感觉Move 语言,进一步了解move虚拟机等。

深刻浅出区块链技术博客,带你了解move语言,走进libra的世界。

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息