跳至内容
0%

什么是 Yul?

发布于 2023年7月28日2 分钟阅读

Yul 是一种中间编程语言,可以在智能合约内部用它写一种形式的汇编语言。虽然我们通常看到 Yul 用在智能合约内部,但你也可以完全用 Yul 编写一个智能合约。

理解 Yul 可以提升你的智能合约水平,让你了解 solidity 底层发生了什么,这反过来能帮你为用户节省 gas 费用。

我们可以通过以下语法在智能合约中识别出 Yul。

在本文接下来的部分,我们将通过示例讨论使用 Yul 的基础知识,建议你在 Remix 中跟着一起操作。

Yul 中的变量赋值、运算与求值

首先要讲的是简单的运算。Yul 有 +、-、、/、%、、<、> 和 =。

注意 >= 和 <= 不在 Yul 可用运算符列表中,因为 Yul 没有这些运算符。此外,求值结果不是 true 或 false,而是分别等于 1 或 0。好了,让我们开始学习一些 Yul 吧!

Instruction
Explanation

let

定义变量前必须使用它。由于所有值都是字节,因此不需要指定变量类型。

:=

Solidity 等价写法:x = y

add(x,y)

Solidity 等价写法:x + y

sub(x,y)

Solidity 等价写法:x - y

mul(x,y)

Solidity 等价写法:x * y

div(x,y)

Solidity 等价写法:x / y(若 y 等于 0 则为 0)

mod(x,y)

Solidity 等价写法:x % y(若 y 等于 0 则为 0)

lt(x,y)

Solidity 等价写法:x < y

gt(x,y)

Solidity 等价写法:x > y

eq(x,y)

Solidity 等价写法:x == y

iszero(x)

Solidity 等价写法:x == 0

在继续之前,我们先来快速看一个例子。

Yul 中的 for 循环与 if 语句

为了学习 for 循环和 if 语句,我们来写一个函数,统计一串数字中有多少个偶数。

if 语句的语法与 Solidity 类似,但条件不需要放在括号里。

对于 for 循环,注意在声明 i 和递增 i 时我们使用了括号,但在判断条件时没有使用。此外,我们用 continue 跳过了循环的某一次迭代。在 Yul 中我们也可以使用 break 语句。

Yul 中存储的工作原理

一个智能合约有 2²⁵⁶ 个存储槽(slot)。声明变量时,我们从槽 0 开始并依次递增。每个槽长 256 位(32 字节);这也是 uint256 和 bytes32 名称的由来。所有变量都会被转换为十六进制。如果使用的是像 uint128 这样的变量,我们不会用整个槽来存储它,而是在左侧用 0 补齐。

想了解更多关于 Yul 存储的工作原理,请阅读我们另一篇涵盖以下内容的文章:

  1. 数组
  2. 动态数组
  3. 映射(Mappings)
  4. 嵌套映射

如何在 Yul 中读写打包(packed)变量

打包变量指的是对变量进行排序,使它们的存储总量小于 32 字节,从而能够一起放入同一个槽中!打包变量可以节省 gas,是智能合约优化的一项重要技巧。

例如,0x0000000000000000000000000000020x000000000000000000000000000001 可以完美地放入同一个槽,因为它们各占 16 字节(半个槽)。

想了解更多如何在 Yul 中读写打包存储变量,请阅读我们的深度解析文章!

Yul 中内存是如何工作的?

内存的行为与存储不同,它不是持久化的(也就是说,函数执行完毕后,所有变量都会被清空)。Yul 中内存的一些用途包括:

  1. 为外部调用返回值
  2. 为外部调用设置函数值
  3. 从外部调用中获取值
  4. 使用错误字符串进行 revert
  5. 记录日志消息

想了解更多关于 Yul 内存的工作原理,请阅读我们另一篇深入探讨该主题的文章!

Yul 中合约调用是如何工作的?

一旦你理解了 Yul 的语法、存储以及内存的工作原理,接下来就该学习如何调用合约了。我们 Yul 系列的最后一篇文章讲解了在 Yul 中如何调用合约,具体包括:

  1. call() - 调用地址 a 处的合约,出错时返回 0,成功时返回 1
  2. staticcall() - 与 call(g, a, 0, in, insize, out, outsize) 相同,但不允许状态修改
  3. delegatecall() - 与 callcode 相同,但同时保留 caller 和 callvalue‍

关于合约调用定义的更多信息,可参阅 Yul 语言文档

Background gradient

构建区块链应用

Alchemy 将最强大的 Web3 开发者产品和工具与资源、社区及专业支持结合在一起。