基本介绍
智能合约是一种在区块链平台上运行的自动化执行协议,它使得合约双方能够在无需中间人或信任第三方的情况下直接进行可信交易,这些交易可追踪且不可逆转。智能合约当中内含了代码函数,亦能与其他合约进行交互,当预定义的条件得到满足时,智能合约会自动执行合约中指定的代码函数。
智能合约概念最早由计算机科学家 Nick Szabo 在上世纪90年代提出,但直到以太坊区块链的出现,智能合约才开始实现广泛应用。以太坊 2015 年推出,支持智能合约的部署和执行,与比特币主要用于加密货币的简单交易不同,能够使用其图灵完备编程语言在以太坊平台上构建去中心化应用,因此被誉为第二代区块链。
智能合约语言是用于编写智能合约的编程语言,编译成字节码后在区块链智能合约平台的虚拟机上执行,实现预定逻辑的代码。一个智能合约语言需要能够使开发者以安全、高效的方式表达合约的规则,并通常提供一系列用于处理区块链事务和状态的工具和抽象。
智能合约语言
智能合约开发者中大多数都在以太坊以及兼容 EVM 的区块链上进行开发,而 Solana 是非 EVM 兼容区块链生态中开发者最多的,Move 则是专门为安全地开发区块链智能合约而构建的。
虽然还有许多其他公链有专门的智能合约语言,例如 TON/FunC、Cardano/Plutus、 ICP/Motoko、Flow/Cadence、Starknet/Cairo 等,但过于碎片化。
因此本文将智能合约语言按照 EVM 系、Solana 系和 Move 系进行分类介绍。
EVM 系
EVM(Ethereum Virtual Machine, 以太坊虚拟机)是以太坊的核心,负责运行智能合约和处理交易。以太坊协议规定了一种运行在 EVM 之上的字节码,并在其之上构建了中间语言 Yul 和 Yul+,在中间语言之上再次构建了 Solidty/Vyper/Fe 等高级语言,高级语言面向前端用户降低智能合约的开发难度。采用多级分层的好处是中间语言既适合于翻译到机器语言,又适合全程序优化,易于手动检查,进行形式化验证等检查,但是分层越多保证可证可信的成本就会更高,每一层都需要做对应的验证,当然越底层的语言由于更简单所以验证成本更低。
在以太坊以及兼容 EVM 的区块链(例如 BSC、Polygon、Avalanche、Arbitrum、Optimism 等)上,开发者可以使用不同的高级编程语言,目前最受欢迎和维护得最好的语言是 Solidity 和 Vyper,此外还可以选择 Yul、Yul+、Fe 和 Huff。
Solidity 最早是由以太坊 CTO Gavin Wood 于 2014 年提出,后期则以 Christian Reitwiessner 所领导的以太坊团队接手开发。Solidity 作为一种面向对象的编程语言,深受 C++、Python 和 JavaScript 的影响,并且专为 EVM 而设计。Solidity 为了代码重用,智能合约被视为类对象,利用了多重继承。特别地,Solidity 规定了一种应用程序二进制接口(ABI)标准来与其合约交互。目前,Solidity ABI 被视为 EVM DSL 的事实标准。
Vyper 则由以太坊创始人之一 Vitalik Buterin 的团队开发,旨在作为 Solidity 的替代选择,于 2017 年推出。Vyper 是一种面向合约的类似于 Python 的编程语言,也是为 EVM 设计的。Vyper 针对安全性、可读性、审计能力和 Gas 效率进行了优化。Vyper 不采用面向对象模式,也不能使用内联汇编。
Yul 是一种具有高级控制流和大量抽象的汇编语言,是 Solidity 工具链的一部分。Yul 中的大多数功能在 Solidity 中使用内联汇编块公开,可以利用 Solidity 不支持的功能,并自定义存储、内存和 calldata。Yul+ 是 Yul 的扩展,可以视为对 Yul 的实验性升级。
Fe 是一种类似 Rust 的高级语言,于 2021 年 1 月发行。Fe 不使用面向对象的模式,而是通过基于模块的系统重用代码,在模块内声明变量、类型和函数,可以以类似于 Rust 的方式进行导入。
Huff 是一种汇编语言,具有手动堆栈控制和对 EVM 指令集的最小化抽象。通过「#include」指令,编译时可以解析任何包含的 Huff 文件,从而实现代码重用。
在以太坊上,基于 Solidity 开发的智能合约占绝大多数,大约 90%,是第二名 Vyper 的十倍,而 Fee 由于起步更晚,鲜有开发者使用。Yul 和 Yul+ 一般作为 Solidity 的内联汇编块,允许对 EVM 指令集进行低级别访问,通常用于 Gas 优化。Huff 比 Yul/Yul+ 更底层,可以手动操作堆栈和调用 EVM 指令,通常用于 Gas 极限优化。
Solana 系
Solana 因其 PoH(Proof of History )机制以及低延迟高吞吐量而闻名,是最著名的“以太坊杀手”之一。Solana 也是过去一年市值和生态发展最快的公链之一,催化了其开发者社区的显著增长。
Solana 将智能合约称为链上程序(Program),主要采用 Rust 语言编写,但与其他采用 Rust 语言的公链(例如 Near、Polkadot/Substrate、CosmWasm)不同,Solana 并不使用 WASM runtime,Solana 有自己独特的虚拟机 SVM 和字节码 SBF。
SVM 是在 Solana 网络上运行智能合约和处理交易的 runtime,关键组件是 Sealevel。Sealevel 通过允许多个智能合约同时运行而不会影响彼此的性能,从而在 Solana runtime 中实现并行处理。Solana 的智能合约指定了在运行时将读取或写入哪些状态(账户),这使得没有冲突的交易可以并行执行,同时保证数据一致性。
SBF 基于 eBPF,前身是 BPF(Berkeley Packet Filter ,伯克利包过滤器),原本是用于网络数据包的高效过滤,eBPF 提供更丰富的指令集,允许在不改动源码的情况下对操作系统内核进行动态干预和修改其行为,具有高性能、安全和可移植性。SBF 相对于 eBPF,使用了一个自定义验证器,不仅会验证程序需要确定程序在一定数量的指令内终止(也就是著名的停机问题),还会检查指令是否正确以及是否有越界跳转。除了验证器之外,还解决了一些对于编译智能合约来说有点问题的 eBPF 细节。
LLVM(Low Level Virtual Machine)是现代化的编译架构和工具链,编译器可以将 Rust 翻译成中间语言 LLVM IR,之后再由 LLVM IR 利用后端翻译成目标平台的 eBPF。理论上,只要支持编译成 LLVM IR 的程序语言都可以编写 Solana 智能合约,但实际上 Solana Labs 对 Rust 和 eBPF LLVM 后端进行了多项更改,其中一些更改本质上不是上游(Rust 和 LLVM)可用的。Solana 合约开发目前只支持 Rust 和 Solang。
Rust 由 Mozilla 主导开发,于 2011 年推出,语法上与 C++ 类似,是一种为性能和安全,尤其是安全而设计的通用的静态编译型语言,并不限于智能合约程序。与 Solidity 相比,Rust 是一种低级(low-level)、多范式的编程语言,性能高且内存安全。Rust 官方的编译器为 rustc,rustc 对 Rust 源码进行词法分析、语法分析、语义分析,最终将代码编译为 LLVM IR。
Solang 由 Hyperlege Labs 主导开发,于 2023 年推出,是 Solana 和 Polkadot 的基于 LLVM 架构的 Solidity 的编译器,支持使用 Solidity 编写智能合约,但实际语法为了与 Solana 和 Polkadot 的体系结构保持一致做了一些改动。Solang 的目的是简化开发人员向 Solana 或 Polkadot 的过渡,并扩大 Solidity 的开发范围。
Rust 是 Solana 官方主要支持的语言,稳定性更强;Solang 主要优势在于其与 Solidity 语言的兼容性。
Move 系
Move 是 Diem (前身 Libra) 设计的一种新的智能合约编程语言,于 2019 年推出,最初是为 Meta 的 Diem 区块链项目而开发的。Move 旨在解决资产和交易中的安全性问题,使得资产和交易能够被严格定义和控制,其语言特点是:
-
一等资源类型的保护 (Frist Class Resources):一等资源类型首先是一种变量类型,然后规定这种类型的变量:不能被复制;不能被隐式地销毁;只能在不同程序地址上“Move”;
-
灵活性:Move 字节码可以直接执行,也可以调用其他已发布的 Modules 代码,可以在一个交易中调用多个程序,能够灵活的实现在一笔交易中给多人转账;
-
安全、可验证性:Move 编码系统为资源提供了针对性的安全保护。Move 资源不可复制,重复使用或销毁。一个资源类型仅能被定义其类型的模块创建或销毁。Move 虚拟机将通过静态字节码验证,并拒绝未通过字节码验证的的程序运行,以此确保其安全性。
在 Diem 项目解散之后,其创始团队出走分别创立的 Aptos 与 Sui,也将 Move 作为核心智能合约语言。Aptos 继承了 Diem Move(Core Move),Sui 则通过自身定制版本的 Sui Move 来编写其智能合约。
在 Move 中,每个智能合约都是一个模块,由函数和结构定义组成,结构在函数中实例化,可以通过函数调用传递给其他模块。Sui Move 相比于 Core Move,采用了一种基于对象的数据模型,Sui 中存在三种不同类型的对象,分别是拥有者对象,共享对象和不可更改对象。Sui 的并行化策略与 Solana 相似,交易也需要指定操作哪些对象,这种设计使得 Sui 可以有效地处理并发交易,实现无需传统区块链所需的全局排序的并行处理能力。
Move 的编译器、验证器以及虚拟机都是从头设计的。其中验证器是 Move 的核心安全机制之一,用于维护 Move 以资源为中心的编程模型。Move 的验证器是一个静态分析工具,分析 Move 字节码并确定是否遵守所需的类型、内存和资源安全规则,所有上传到链上的模块都需要通过验证器。
相比于 Solidity 等语言,Move 是一种对形式化验证友好的语言,比如不支持动态指派(dynamic dispatch)等特性,所有合约路径都可以在编译期就确定,而无需在合约执行时才确定需要执行的函数,可以充分的进行分析和验证。
Move 还有一个用于智能合约的形式化验证工具,称为 Move Prover。开发者需要针对智能合约编写验证条件(以断言的形式),Move Prover 会在后台将这些验证条件转换为 SMT 公式,然后使用 SMT 求解器进行检查。
智能合约开发工具
对于想入门 Web3 或者想学习以太坊及其他兼容 EVM 的区块链的合约开发者而言,Solidity 都是不二之选。并且由于 Solidity 的流行,开发工具也更加成熟,代表有:
-
Hardhat 是一个编译、部署、测试和调试以太坊应用的开发环境。帮助开发人员管理和自动化构建智能合约和 DApps 过程中固有的重复性任务,并围绕这一工作流程轻松引入更多功能;
-
OpenZeppelin 提供开源的 OpenZeppelin Contracts,用 Solidity 编写,用于构建安全的智能合约。OpenZeppelin Contracts 使用 ERC 标准,可用于许多类型的项目;
-
Foundry 是一个 Solidity 框架,用于构建、测试、模糊、调试和部署 Solidity 智能合约, Foundry 的优势是以 Solidity 作为第一公民,完全使用 Solidity 进行开发与测试。
Solana 是开发者在以太坊之外的第二种选择,Rust 语言的应用场景也非常广泛。但 Solana 合约编程模型相对复杂,Rust 语言学习曲线相对陡峭,对开发者造成不小的开发难度。Solana 的开发框架 Anchor,可以类比 Solidity 的开发框架 Hardhat,通过减少诸如账户(反)序列化和指令数据等领域的样板文件、进行必要的安全检查、自动生成客户端库以及提供广泛的测试环境来简化 Solana 开发流程。
Move 语言在底层的安全设计上有重大的创新,在保证语言表达能力和灵活性的同时,也让 DApps 更加安全可靠。但目前基于 Move 的公链只有 Aptos 和 Sui,都是新兴公链,开发工具也不够完善。
总结
分析和评价智能合约开发语言通常包含易用性(是否容易上手和掌握)、安全性(是否能减少安全漏洞的出现)和生态资源(是否有丰富的开发工具和类库)。
Solidity 是影响力最大的智能合约开发语言,通过开源社区的形式,积累了大量的成熟的开发工具和类库,可以简化开发流程,复用安全约束,有助于实现业务的快速开发。
Rust 弥补了 Solidity 的安全性,虽然学习难度让人望而生畏,但 Solana 生态仅次于以太坊,对开发者有足够的吸引力,并且 Solang 也能链接 EVM 和 Solana 生态。
Move 基于 Rust 编写,底层增加了更多安全机制,能保障资产守恒,学习难度也对开发者更加友好,但生态发展过于早期,距离大规模的工程化使用仍然有一定的距离。