智能合约语言
页面最后更新: 2025年10月22日
关于以太坊的一个重要方面是,智能合约可以使用相对友好的开发者语言编程。 如果你有 Python 或任何花括号语言opens in a new tab的经验,你可以找到一种语法熟悉的语言。
最受欢迎和维护得最好的两种语言是:
- Solidity
- Vyper
Remix 集成开发环境提供了一个全面的开发环境,用于创建和测试用 Solidity 和 Vyper 语言编写的智能合约。 试用浏览器内置的 Remix IDEopens in a new tab 开始编码。
经验更丰富的开发者可能还想使用 Yul(一种用于以太坊虚拟机的中间语言)或 Yul+(Yul 的扩展)。
如果你很好奇,喜欢帮助测试仍在大力发展的新语言,则可以尝试使用 Fe,这是一种新兴的智能合约语言,目前仍处于起步阶段。
前提条件
如果已经有编程语言(特别是关于 JavaScript 或 Python)知识,可以帮助你体验到智能合约语言的差异。 同时,我们建议你在深入理解语言差异之前,先理解作为概念的智能合约。 智能合约简介。
Solidity
- 执行智能合约的目标导向高级语言。
- 受 C++ 影响最深的大括号编程语言。
- 静态类型(编译时已知变量类型)。
- 支持:
- 继承(你可以拓展其它合约)。
- 库(你可以创建从不同的合约调用的可重用代码 - 就像静态函数在其它面向对象编程语言的静态类中一样)。
- 复杂的用户自定义类型。
重要链接
- 文档opens in a new tab
- Solidity 语言门户opens in a new tab
- Solidity 示例opens in a new tab
- GitHubopens in a new tab
- Solidity Gitter 聊天室opens in a new tab桥接至 Solidity Matrix 聊天室opens in a new tab
- 速查表opens in a new tab
- Solidity 博客opens in a new tab
- Solidity Twitteropens in a new tab
示例合约
1// SPDX-License-Identifier: GPL-3.02pragma solidity >= 0.7.0;34contract Coin {5 // 关键字“public”使变量6 // 可从其他合约访问7 address public minter;8 mapping (address => uint) public balances;910 // 事件允许客户端对你声明的特定11 // 合约更改做出反应12 event Sent(address from, address to, uint amount);1314 // 构造函数代码仅在创建15 // 合约时运行16 constructor() {17 minter = msg.sender;18 }1920 // 将一定数量的新创建的代币发送到一个地址21 // 只能由合约创建者调用22 function mint(address receiver, uint amount) public {23 require(msg.sender == minter);24 require(amount < 1e60);25 balances[receiver] += amount;26 }2728 // 从任何调用者向一个地址29 // 发送一定数量的现有代币30 function send(address receiver, uint amount) public {31 require(amount <= balances[msg.sender], "余额不足。");32 balances[msg.sender] -= amount;33 balances[receiver] += amount;34 emit Sent(msg.sender, receiver, amount);35 }36}显示全部这个示例应该能让你感觉到 Solidity 合约语法是什么样子的。 有关函数和变量的更详细说明,请参阅文档opens in a new tab。
Vyper
- 类 Python 编程语言
- 强类型
- 小而且易懂的编译器代码
- 高效的字节码生成
- 为了让合约更安全和易于审核,特意提供比 Solidity 少的功能。 Vyper 不支持:
- 修改器
- 继承
- 内联汇编
- 函数重载
- 操作符重载
- 递归调用
- 无限长度循环
- 二进制定长浮点
更多信息,请阅读 Vyper 的设计原理opens in a new tab。
重要链接
- 文档opens in a new tab
- Vyper 示例opens in a new tab
- 更多 Vyper 示例opens in a new tab
- GitHubopens in a new tab
- Vyper 社区 Discord 聊天opens in a new tab
- 速查表opens in a new tab
- 适用于 Vyper 的智能合约开发框架和工具
- VyperPunk - 学习如何保护和破解 Vyper 智能合约opens in a new tab
- 用于开发的 Vyper Hubopens in a new tab
- Vyper 智能合约最佳示例opens in a new tab
- Awesome Vyper 精选资源opens in a new tab
示例
1# 公开拍卖23# 拍卖参数4# 受益人从最高出价者处收款5beneficiary: public(address)6auctionStart: public(uint256)7auctionEnd: public(uint256)89# 拍卖的当前状态10highestBidder: public(address)11highestBid: public(uint256)1213# 结束时设置为 true,不允许任何更改14ended: public(bool)1516# 跟踪已退还的出价,以便遵循取款模式17pendingReturns: public(HashMap[address, uint256])1819# 创建一个简单拍卖,代表受益人地址 `_beneficiary`,20# 拍卖时间为 `_bidding_time` 秒。21@external22def __init__(_beneficiary: address, _bidding_time: uint256):23 self.beneficiary = _beneficiary24 self.auctionStart = block.timestamp25 self.auctionEnd = self.auctionStart + _bidding_time2627# 使用与此交易一起发送的价值对拍卖进行出价。28# 只有未赢得拍卖,29# 价值才会被退还。30@external31@payable32def bid():33 # 检查出价期是否结束。34 assert block.timestamp < self.auctionEnd35 # 检查出价是否足够高36 assert msg.value > self.highestBid37 # 跟踪先前最高出价者的退款38 self.pendingReturns[self.highestBidder] += self.highestBid39 # 跟踪新的最高出价40 self.highestBidder = msg.sender41 self.highestBid = msg.value4243# 取回先前已退还的出价。此处使用取款模式44# 以避免安全问题。如果退款直接45# 作为 bid() 的一部分发送,恶意出价合约可能会阻止46# 这些退款,从而阻止新的更高出价进入。47@external48def withdraw():49 pending_amount: uint256 = self.pendingReturns[msg.sender]50 self.pendingReturns[msg.sender] = 051 send(msg.sender, pending_amount)5253# 结束拍卖并将最高出价54# 发送给受益人。55@external56def endAuction():57 # 一个好的指导原则是将与其他合约交互的函数(即调用函数或发送以太币)58 # 结构化为三个阶段:59 # 1. 检查条件60 # 2. 执行操作(可能会改变条件)61 # 3. 与其他合约交互62 # 如果这些阶段混合在一起,另一个合约可能会回调63 # 到当前合约并修改状态或导致64 # 效果(以太币支付)被多次执行。65 # 如果内部调用的函数包含与外部合约的交互,66 # 它们也必须被视为与67 # 外部合约的交互。6869 # 1. 条件70 # 检查是否已达到拍卖结束时间71 assert block.timestamp >= self.auctionEnd72 # 检查此函数是否已被调用73 assert not self.ended7475 # 2. 效果76 self.ended = True7778 # 3. 交互79 send(self.beneficiary, self.highestBid)显示全部这个例子应该让你了解 Vyper 合约语法是什么样的。 有关函数和变量的更详细说明,请参阅文档opens in a new tab。
Yul 和 Yul+
如果你是以太坊的新手并且尚未使用智能合约语言进行任何编码,我们建议你开始使用 Solidity 或 Vyper。 只有在你熟知智能合约安全最佳做法和使用 EVM 的具体细节后,才可以查看 Yul 或 Yul+。
Yul
- 以太坊的中继语言。
- 支持 EVM 和 Ewasmopens in a new tab(一种以太坊风格的 WebAssembly),旨在成为这两个平台的通用分母。
- 是高级优化阶段的理想目标,可使 EVM 和 Ewasm 平台同等受益。
Yul+
- Yul 的低级、高效扩展。
- 最初为乐观卷叠合约而设计。
- Yul+ 可以被视为对 Yul 的实验性升级建议,为其添加新功能。
重要链接
示例合约
以下简单示例实现了幂函数。 可以使用 solc --strict-assembly --bin input.yul 对其进行编译。 这个例子应该
存储在 input.yul 文件中。
1{2 function power(base, exponent) -> result3 {4 switch exponent5 case 0 { result := 1 }6 case 1 { result := base }7 default8 {9 result := power(mul(base, base), div(exponent, 2))10 if mod(exponent, 2) { result := mul(base, result) }11 }12 }13 let res := power(calldataload(0), calldataload(32))14 mstore(0, res)15 return(0, 32)16}显示全部如果你对智能合约已非常有经验,可以在此处opens in a new tab找到用 Yul 实现的完整 ERC20。
Fe
- 以太坊虚拟机 (EVM) 静态类型语言。
- 受到 Python 和 Rust 的启发。
- 目标是容易学习 - 甚至对以太坊生态系统为新的开发者来说也是如此。
- Fe 开发仍处于早期阶段,该语言于 2021 年 1 月发行。
重要链接
- GitHubopens in a new tab
- Fe 公告opens in a new tab
- Fe 2021 路线图opens in a new tab
- Fe Discord 聊天opens in a new tab
- Fe Twitteropens in a new tab
示例合约
以下是在 Fe 中执行的简单的智能合约。
1type BookMsg = bytes[100]23contract GuestBook:4 pub guest_book: map<address, BookMsg>56 event Signed:7 book_msg: BookMsg89 pub def sign(book_msg: BookMsg):10 self.guest_book[msg.sender] = book_msg1112 emit Signed(book_msg=book_msg)1314 pub def get_msg(addr: address) -> BookMsg:15 return self.guest_book[addr].to_mem()显示全部如何选择
与任何其他编程语言一样,它主要是关于为合适的工作以及个人喜好选择合适的工具。
如果你还没有尝试过任何一种语言,请考虑以下几点:
Solidity 的优点是什么?
- 如果你是初学者,这里有很多教程和学习工具。 在“通过编码学习”部分查看更多相关信息。
- 提供出色的开发者工具。
- Solidity 拥有庞大的开发人员社区,这意味着你很可能会很快找到问题的答案。
Vyper 的优点是什么?
- 想要编写智能合约的 Python 开发人员入门的好方法。
- Vyper 的功能较少,因此非常适合快速制作创意原型。
- Vyper 旨在易于审计并最大限度地提高人类可读性。
Yul 和 Yul+ 的优点是什么?
- 简单而实用的低级语言。
- 允许更接近原始 EVM,这有助于优化合约的燃料使用量。
语言比较
要比较基本语法、合约生命周期、接口、运算符、数据结构、函数、控制流等,请查看 Auditless 制作的这份速查表opens in a new tab