# 智能合约发展:全方位对比Move与Rust **Published by:** [0X39F](https://paragraph.com/@edenswap/) **Published on:** 2022-09-09 **URL:** https://paragraph.com/@edenswap/move-rust ## Content 介绍 最近,关于 Aptos 和 Sui 的讨论如火如荼,两者是新兴的高性能 L1 公链,Move 智能合约编程语言是这些新链必不可缺的组成部分。一些开发人员正在积极转向Move,宣称它是智能合约发展的未来。其他人更加谨慎,认为 Move 与现有编程语言相比,不能提供更多太新的东西。加密投资者也在好奇这些 L1 公链的独特之处,如何能与 Solana 抗衡,后者是目前高性能 L1 的主要玩家,以使用 Rust 作为智能合约编程而著称。 但目前我们看到的讨论并没有达到一定深度,能够真正参透这些新科技对我们的影响。这在讨论的两极都适用——Move 的质疑者将 Move 贬低得一无是处,无法欣赏到它更细微(但十分重要)的一面,但 Move 的支持者,过度鼓吹 Move,也没有能看透究竟是什么使其伟大。这就带来巨大的中间地带与模糊不清,致使外界看客、加密开发人员、投资人员,关注此话题,但又无法对自己的观点确信。 在这篇文章中,我将对 Move、其新颖的编程模型、Sui 区块链和它如何利用 Move 的功能,以及它与 Solana 及其编程模型的比较进行深入的技术挖掘。为了突出 Move 的特点,我将把 Solana/Rust 与 Sui/Move 进行比较。因为当你把一个东西与另一个你已熟悉的东西进行比较时,理解就会更容易。 Move 还有其他变种,如 Aptos Move,它们在某些方面略有不同。本文的重点不是讨论 Move 不同变体之间的细微差别,而是展示 Move 的普遍优势,以及它与 Solana 编程模型的比较。因此为了简单起见,我在本文中只使用一个变体(Sui Move)。因此,我在本文中介绍的某些Move概念(即对象和相关功能)只适用于 Move 的 Sui 变体,而不适用于其他变体。虽然 Move 的其他变体不一定有这些概念,但它们使用不同的机制(例如全局存储)能够实现同样功能。但即便如此,本文所讨论的所有Move的主要优点都适用于所有Move集成(原生设定上支持Move字节码 Move bytecode),包括Aptos。我选择Sui,只是因为我对它更熟悉,且我觉得它更直观一些,更容易以文章的形式呈现。Solana编程模型 在Solana上,程序(智能合约)是无状态的,它们自己不能访问(读或写)任何在整个交易中持续存在的状态。为了访问或保持状态,程序需要使用账户。每个账户都有一个唯一的地址(Ed25519密钥对的公钥),可以存储任意的数据。我们可以把Solana的账户空间看作是一个全球键值存储,其中键是账户地址(pubkey),值是账户数据。程序通过读取和修改其值在该键值存储上进行操作。 账户有一个所有权的概念。每个账户由一个(且只有一个)程序拥有。当一个账户被一个程序拥有时,该程序被允许修改其数据。程序不能修改所不拥有的账户(但允许读取这些账户)。运行期间,比较程序执行前后的账户状态,就能够进行这种动态检查,若有非法改动,则交易失败。 每个账户也有一个与之相关的私钥(相应的公钥是它的地址),能够访问这个私钥的用户可以用它来签署交易。利用这种机制,我们在Solana智能合约中实现了权限和所有权的功能--例如,为了获取某些资金,智能合约可以要求用户提供必要的签名。 在其他做程序调用时,客户需要指定这个程序在调用时将访问哪些账户。这样一来,交易处理运行时间就可以安排不重迭的交易并行执行,同时保证数据一致性。这是Solana的设计特点之一,使其具有高吞吐量。 程序可以通过CPI调用来调用其他程序。这些调用的工作原理与来自客户端的调用基本相同——调用者程序需要指定被调用者程序将访问的账户,被调用者程序将进行输入检查,就和从客户端调用是一样的(因为它不信任调用者程序)。 PDA账户是一种特殊账户,使程序能在不拥有或储存私钥的情况下提供账户签名。PDA保证只有为其生成PDA的程序可以为其创建一个签名(而其他用户和程序不行)。当一个程序需要通过CPI调用与另一个程序进行交互并提供授权时,这是很有用的(例如,实施一个金库)。PDA保证除了程序之外没有人可以直接访问程序资源。PDA也可用于在确定地址创建账户。 这些是Solana上安全智能合约编程的基本构件。在某种程度上,你可以把Solana程序看作是操作系统中的程序,而账户则是文件,任何人都可以自由执行任何程序,甚至部署自己的程序。当程序(智能合约)运行时,它们将读取和写入文件(账户)。所有文件都可被所有程序读取,但只有对文件有所有权权限的程序才可以对其进行改写。程序也可以执行其他程序,但它们彼此之间没有任何信任——无论谁执行程序,它都需要假设输入是潜在恶意的。由于该操作系统是任何人在全球范围内都访问的,所以在程序中加入了原生签名验证支持,以便为用户实现权限和所有权功能......这不是一个完美的比喻,但还是挺有趣的。Move的编程模型 在Move中,智能合约是以模块形式发布的。模块由函数和自定义类型(结构/struct)组成。结构由字段组成,可以是原始类型(u8,u64,bool...)或其他结构。函数可以调用其他函数——可以是同一模块,也可以是其他公开的模块。在Solana中,这就相当于所有智能合约都作为模块发布在一个程序中。这意味着所有的智能合约(模块)都包含在同一类系统中,可以直接相互调用,而不需要通过中间的API或接口。这一点非常重要,其影响将在本文中彻底讨论。 3.1. 对象 要注意的是,下面的对象概念针对于Move的Sui变体。而在Move的其他集成中(例如Aptos或Diem/core Move),情况可能略有不同。不过,在其他Move变体中也有类似的解决方案,可以实现同样的事情(状态的持久性),这些解决方案并没有太大区别。 这里介绍Sui变体的主要原因是,文章后面的代码样本都基于Move的Sui变体,同时其对象比如core Move中的全局存储机制更直观易懂一点。重要的是,本文所讨论的Move的所有主要优点都适用于所有Move集成(原生支持Move字节码),包括Aptos。 对象是由运行时存储的结构实例(struct instance),并在事务中持续保持状态。 有三种不同类型的对象(在Sui中):自有对象(owned objects)共享对象(shared objects)不可变对象(immutable objects)自有对象是属于用户的对象。只有拥有该对象的用户才能在交易中使用它。所有权元数据是完全透明的,由运行处理。它使用公钥加密技术实现——每个自有对象都与一个公钥关联(运行时存储在对象元数据中),任何时候你想在交易中使用对象,你都需要提供相应签名(现在支持Ed25519,即将支持ECDSA和K-of-N多签名)。 共享对象类似于自有对象,但它们没有一个与之相关的所有者。因此,你不需要拥有任何私钥就可以在交易中使用它们(任何人都可以使用它们)。任何自有对象都可以被共享(由其所有者),一旦一个对象被共享,它将永远保持共享——永远不能被转移或再次成为自有对象。 不可变对象是不能被改动的对象。一旦一个对象被标记为不可变,它的字段就不能再被修改。与共享对象类似,这些对象没有所有者,可以被任何人使用。 Move编程模型非常直观和简单。每个智能合约是一个模块,由函数和结构定义组成。结构在函数中被实例化,并可以通过函数调用传递到其他模块。为了使一个结构能够在跨交易中保持持久,我们把它变成一个可以被拥有、共享或不可改变的对象(仅限于Sui,在其他Move变体中略有不同)。Move的安全性 我们已经看到,在Move:你可以将你拥有(或共享)的任何对象传递给任何模块中的任何函数任何人都可以发布一个(潜在的敌对)模块不存在模块拥有结构的概念,这将使所有者模块拥有改变结构的唯一权力,就像Solana账户的情况一样——结构可以流入其他模块,也可以嵌入其他结构中。问题是,这种做法为什么是安全的?是什么阻止了人们发布恶意模块,获取共享对象(如AMM池),并将其发送到恶意模块中,然后继续耗尽其资金? 在Solana中,有一个账户所有权的概念,也就是说只有拥有账户的程序才被允许对其进行改动。但是在Move中,没有模块拥有对象的概念,你可以将对象发送到任意的模块中——不仅可以引用对象、整个对象,也可以引用其本身价值。而且,运行时也没有具体检查,以确保这个对象在通过不受信模块时没有被非法修改。那么,是什么在保护这个对象的安全?如何保证这个对象不被不可信的代码滥用? 这就是Move的新颖之处......让我们来谈谈资源。 ## Publication Information - [0X39F](https://paragraph.com/@edenswap/): Publication homepage - [All Posts](https://paragraph.com/@edenswap/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@edenswap): Subscribe to updates - [Twitter](https://twitter.com/MabelChamberl18): Follow on Twitter