# 智能合约开发工具Remix

By [Keegan小钢](https://paragraph.com/@keeganlee) · 2024-10-21

---

不久前，我在B站、视频号和 YouTube 都陆续发布了新的一套免费视频课程《[**智能合约开发工具Remix**](https://space.bilibili.com/60539794/channel/collectiondetail?sid=3980129)》，总共分为了 9 个小节的视频，以下分别是这 9 个小节在 B 站的视频链接，喜欢直接看视频的伙伴可以去 B 站观看：

1.  [**概况**](https://www.bilibili.com/video/BV1iS2WYSENu/?spm_id_from=333.999.0.0)
    
2.  [**文件浏览器**](https://www.bilibili.com/video/BV16n2VYfEke/?spm_id_from=333.999.0.0)
    
3.  [**remixd**](https://www.bilibili.com/video/BV1aq21YMEV1/?spm_id_from=333.999.0.0)
    
4.  [**Git插件**](https://www.bilibili.com/video/BV1XZ22YkE3U/?spm_id_from=333.999.0.0)
    
5.  [**编辑器**](https://www.bilibili.com/video/BV1q92tYYEdU/?spm_id_from=333.999.0.0)
    
6.  [**编译器&AI工具**](https://www.bilibili.com/video/BV1c22tYuEoy/?spm_id_from=333.999.0.0)
    
7.  [**部署&发交易**](https://www.bilibili.com/video/BV1tp2YYFEHi/?spm_id_from=333.999.0.0)
    
8.  [**调试器**](https://www.bilibili.com/video/BV17A2dYGEW9/?spm_id_from=333.999.0.0)
    
9.  [**单元测试**](https://www.bilibili.com/video/BV1KcmPY1E1b/?spm_id_from=333.999.0.0)
    

也可以在 B 站直接搜索「Keegan小钢」找到我，可以看到我目前发布的所有视频课程。截止到当前，我总共已经发布了 5 个视频合集：

*   [**转型Web3开发第一课**](https://space.bilibili.com/60539794/channel/collectiondetail?sid=3291813)
    
*   [**转型Web3开发第二课**](https://space.bilibili.com/60539794/channel/collectiondetail?sid=3409922)
    
*   [**Web3 Dapp开发学习路线图**](https://space.bilibili.com/60539794/channel/collectiondetail?sid=3581225)
    
*   [**Solidity编码规范**](https://space.bilibili.com/60539794/channel/collectiondetail?sid=3780183)
    
*   [**智能合约开发工具Remix**](https://space.bilibili.com/60539794/channel/collectiondetail?sid=3980129)
    

而对于智能合约开发工具Remix这套课程，下面我再对每一节的视频，罗列出一些重点内容。

**1\. 概况**
----------

这一小节主要介绍了Remix的基本概况。

首先，记住 Remix 的正确域名是 [**https://remix.ethereum.org**](https://remix.ethereum.org/)，避免被钓鱼。

其次，官方支持的浏览器只有 **Firefox, Chrome, Brave** 这三款而已，其他浏览器也许可以用，但不保证使用过程中会出现问题。

Remix 整个页面的布局主要分为了：

*   **图标面板**：放置各种插件图标
    
*   **侧边面板**：插件所显示的内容面板
    
*   **主面板**：主页和编辑器面板
    
*   **终端**：输出交易记录和日志等信息
    

默认插件有：**文件浏览器、全文搜索、编译器、部署&发交易、Git**。可以通过插件管理器添加和移除其他插件，常用的包括 **Remixd、调试器、单元测试插件**等。

切换不同插件时，侧边面板就会展示对应插件的内容页面。

**2\. 文件浏览器**
-------------

文件浏览器插件，顾名思义，就是管理文件的。

第一个要熟悉的就是 **Workspace**，即**工作空间**，每一个工作空间就是一个项目。

有多种方式可以用来创建一个新的工作空间。可以创建一个空的工作空间，也可以基于模板创建，Remix 提供了很多模板。还可以通过克隆一个 Git 仓库的方式来创建。

可以创建多个不同的工作空间，也可以在不同的工作空间之间进行切换。

还可以对工作空间进行**重命名、下载、删除、备份、恢复**等操作。还可以通过 Remixd 插件连接到本地文件系统，关于 Remixd 部分则在第 3 小节中有详细介绍。

在工作空间下，也支持多种操作，除了直接创建文件和文件夹之外，还可以将本地文件系统的文件和文件夹加载上传到当前工作空间，也可以从 IPFS 或 https 方式导入文件。最后，还可以将当前工作空间初始化为一个 Git 项目。

**3\. remixd**
--------------

默认情况下，Remix 里添加的文件是存储在浏览器自带的数据库 **IndexedDB** 里的，而浏览器数据库的存储并不是永久性的存储，所以建议增加其他文件备份和存储方案。使用 **Remixd** 把文件存储到本地的文件系统里就是其中一种推荐的方案。

要使用 remixd，需要在你的本地系统里先安装 remixd 命令行工具，可通过执行以下 npm 命令来安装：

> npm install -g @remix-project/remixd

本地连接到 Remix 时，为了保证正常使用，要确保 remixd 已经更新到最新版本。可通过 `remixd -v` 或 `remixd --version` 命令查看 remixd 的版本。如果版本还不是最新的，可直接通过以上安装命令升级更新到最新版本。

安装好 remixd 后，下一步可通过执行以下命令来启动 remixd：

> remixd -s -u [https://remix.ethereum.org](https://remix.ethereum.org)

其中， 需要更换成你要连接的本地目录，比如，我要连接到 `./shared_project` 目录，则实际执行的命令如下：

> remixd -s ./shared\_project -u [https://remix.ethereum.org](https://remix.ethereum.org)

启动成功后，在 Remix 里就可点击 “Connect to Local Filesystem” 打开确认连接到本地的弹出窗口，再点击 “Connect” 按钮就可建立连接了。

连接成功后，就会创建一个新的工作空间，与本地连接的目录相同。在 Remix 里对该工作空间的任何操作，都会同步到本地连接的目录中。同样的，对本地目录下的文件修改，也会同步到 Remix 里的工作空间里。

在本地执行 remixd 的终端窗口里，使用 `ctrl-c` 就可以关闭 remixd 了，也意味着断开了与 Remix 的连接。

**4\. Git插件**
-------------

使用 Git 插件把 Remix 工作空间里的文件修改同步到 Git 远程仓库，也是推荐的另一种文件存储方案。

那要使用 Git，第一步需要先设置 Github 账号。进入 Git 插件面板，打开 **GITHUB SETUP** 选项卡，有两种设置方案：一是 **Login with GitHub**，会教你用三步骤来连接你的 Github 账号；二是手动输入你的 Git 用户名、邮箱和 Github token。

设置好 Github 账号之后，可以通过当前 Git 插件面板的 **Initialize repository** 按钮把当前工作空间初始化为 Git 项目。也可以创建一个新项目并勾选 ”Initialize workspace as a new git repository“。

当前工作空间变成一个 Git 项目之后，Git 插件面板所展示的选项卡也会多了很多。所有选项卡为:

*   **SOURCE CONTROL**：主要是做提交和同步操作
    
*   **COMMANDS**：可以执行 pull、push 和 fecth 操作
    
*   **COMMITS**：展示每一次提交
    
*   **BRANCHES**：用于创建分支、切换分支等
    
*   **REMOTES**：管理远程仓库地址
    
*   **CLONE**：克隆操作
    
*   **GITHUB SETUP**：设置Github
    
*   **LOG**：日志
    

完成了上一步的初始化之后，下一步需要设置远程仓库地址，在 Git 插件面板里的 **REMOTES** 选项卡里进行设置。

设置完之后，就可以对项目进行编码修改了，完成修改后。可通过 **SOURCE CONTROL** 添加 `Commit` 后执行 `Sync Changes`，就完成把代码推送到远程仓库了。

**5\. 编辑器**
-----------

Remix 的编辑器，是和 VS Code 使用的同一款编辑器。其支持 Solidity、JS 和 TS 三种语言的代码高亮。

默认情况下，有三个特性很有用：

*   **代码自动补全**
    
*   **展示 gas 预算**
    
*   **展示错误提示**
    

编码时，对于关键字和已声明的变量、函数名等都会有自动补全和提示功能。

对于每个函数，在函数右侧则会展示该函数的 gas 预算。

而对于代码中的 error 和 warning 则会用不同颜色的波浪线标记出来。

这几个特性都可在设置中进行开启或关闭，默认就是开启的。

另外，在编辑器中打开右键菜单，还可看到一个 ”Format Code“ 的选项，可以对当前代码进行代码风格格式化，使其符合代码规范，这一点也很方便。

**6\. 编译器&AI工具**
----------------

编译器可以结合AI工具一起使用，比较方便。

编译器面板很简单，首先，可以选择编译器的版本，从 0.1.1 到最新版本全都有。其次，建议勾选上 "'**Auto compile**" 选项，则代码变更后会自动编译。然后，打开 ”**Advanced Configuration**“，建议把 ”**Enable optimization**“ 也给勾选上，值设为默认的 200 即可。

当代码里出现 `error` 和 `warning` 时，在编译器面板里也会显示出这些错误提示信息，且在每个错误提示信息下面会有个 ”**Ask RemixAI**“ 的按钮，点击它，RemixAI 会针对该错误提示给出相应的回答，展示在终端面板里。

另外，在主面板左上角有个机器人的小图标，点击该小图标右边的切换按钮，还可启用 **RemixAI Copilot**。启用之后，能够增强代码自动补全的功能。比如，启用 RemixAI Copilot 后，进行 import 时，会自动显示出可导入的合约，包括第三方库如 `@openzeppelin` 和 `@uniswap`，这一点非常方便。再比如，当你要定义一个函数时，输入完 `function` 后，也会给你提示可能想实现的函数声明，按 `tab` 键就可以自动补全整个函数声明，然后再根据自己实际要实现的代码进行调整即可。

编译器面板上有两个编译按钮，背景蓝色的按钮就只是编译合约文件，而灰色背景的 “**Compile and Run script**” 按钮则会在编译完成后自动执行指定的脚本文件。前提是在合约文件头部需要有声明 `@custom:dev-run-script` 的注解，并指定了要执行的脚本文件。比如，示例中的 `Storage` 合约的注解为`@custom:dev-run-script ./scripts/deploy_with_ethers.ts`，声明了 `deploy_with_ethers.ts` 脚本文件，该文件用 `ethers` 编写了部署 `Storage` 合约的脚本。那点击 “**Compile and Run script**” 按钮后，编译完 `Storage` 合约后，就会自动执行 `deploy_with_ethers.ts` 脚本，完成 `Storage` 合约的部署，部署成功的合约地址会在终端中打印出来。

在编译器面板最后有 **ABI** 和 **Bytecode** 两个选项，可以复制当前合约的 **ABI** 和 **Bytecode**，前端和后端需要和合约交互时就需要用到。

**7\. 部署&发交易**
--------------

部署&发交易插件，先说部署。

第一步，选择部署的环境，即合约要部署的网络环境。默认下拉列表中有多个选项，点击列表中最后一项 “**Customize this list...**" 可以打开所有网络环境的列表。下面就只介绍最常用的几个。

*   **Injected Provider - MetaMask**：直接连接你浏览器中的 MetaMask 钱包，你的 MetaMask 钱包当前连接到哪个网络环境就使用哪个环境，钱包账户也是直接使用你的 MetaMask 账户。
    
*   **Remix VM（Cancun）**：默认的内嵌浏览器的一个沙箱网络，并提供了 15 个默认账户，每个账户有 100 ether。
    
*   **Remix VM - Mainnet fork**：fork 自主网的浏览器沙箱网络，也提供了 15 个默认账户，每个账户有 100 ether。
    
*   **WalletConnect**：通过 WalletConnect 连接钱包
    

**GAS LIMIT** 部分一般直接选择默认的 `Estimated Gas` 即可，无需自定义数值。

**VALUE** 即需要转给合约的原生代币金额，即 `msg.value` 的值。

**CONTRACT** 里可选择要部署的合约，一般默认就是当前合约。

**Deploy** 就是部署按钮了，如果合约构造函数存在参数，则部署按钮旁边会显示出输入框，以输入参数。

部署成功后，在最下面的 **Deployed Contracts** 会展示出所部署合约的选项卡，打开它可以和合约进行交互。其中，蓝色背景的按钮是可读函数，橙色背景的按钮则是写函数。

还有个 **At Address** 按钮，也可用于加载合约到 **Deployed Contracts** 列表里进行合约交互。使用 **At Address**，有两种方式，一是**CONTRACT** 里选择要加载的合约代码，不一定需要完整合约代码，就算是只有 `interface` 也行；另一种方式，则是加载 `abi` 文件，视频里就使用了 `IERC20.abi` 作为示例演示。

**8\. 调试器**
-----------

调试器插件，顾名思义，就是 Debug 用的。

有两种方式可以启动 Debug。第一种方式，直接在调试器面板中输入交易哈希，如果代码有 verify 的话，Remix 会尝试从 **Sourcify** 或 **Etherscan** 获取源代码。第二种方式，也是更常用的方式，则是通过部署&发交易插件发起的交易，在终端里显示出每一笔交易时，右侧有个 **Debug** 按钮，点击该按钮就可启动 Debug 了。

Debug 时的基本操作有：

*   **Step into**：单步前进到下一个操作码，如果有子函数调用则会进入子函数
    
*   **Step back**：单步回退到上一个操作码
    
*   **Step over forward**：单步前进到下一个操作码，如果有子函数调用则不会进入子函数
    
*   **Step over back**：单步向后回退到上一个操作码，如果有子函数调用则不会进入子函数
    
*   **Jump to next breakpoint**：跳转到下一个断点
    
*   **Jump to brev breakpoint**：跳转到上一个断点
    
*   **Jump out**：跳出
    
*   **Stop debuging**：停止调试
    

面板中会展示出很多信息，最核心的就是操作码面板，会显示当前执行到第几步和对应的操作码。

另外，还有以下子面板：

*   **Function Stack**：函数栈
    
*   **Solidity State**：显示合约的状态变量
    
*   **Solidity Locals**：局部变量，包括函数参数
    
*   **Step details**：当前操作码的详细信息
    
*   **Call Stack**：调用栈
    
*   **Full Storage Changes**：显示函数末尾的持久化存储
    
*   **Stack**：EVM 栈
    
*   **Call Data**：包含了函数参数的 calldata
    
*   **Memory**：内存面板
    
*   **Storage**：持久存储面板
    
*   **Return Value**：返回值
    
*   **Global Variables**：全局变量
    

**我在实际测试时，其实这些面板通常展示的信息并不全，比如，Solidity State 面板并没有显示出状态变量，Solidity State 也没有显示出全部局部变量，Return Value 也并没有显示出返回值。**

**9\. 单元测试**
------------

最后一个插件，单元测试插件。

Remix 的单元测试插件支持的是 solidity 语言编写的单元测试用例代码。其用来声明断点的库文件是 `remix_tests.sol`，其中定义了 `Asset` 库，以及有多个 `equal`、`notEqual`、`greaterThan`、`lessThan` 等函数。另外，还有一个 `remix_accounts.sol` 文件，其定义了 `TestsAccounts` 库，可通过其 `getAccount` 函数获取测试账户。

单元测试用例函数通常是以 `checkXXX` 命名的。另外，还有四个特殊函数：

*   `beforeEach()` - 会在每个单元测试用例之前执行
    
*   `beforeAll()` - 会在所有单元测试用例之前执行，只执行一次
    
*   `afterEach()` - 会在每个单元测试用例之后执行
    
*   `afterAll()` - 会在所有单元测试用例之后执行，只执行一次
    

编写单元测试时，还可以通过添加注解 `#sender: account-{N}` 和 `#value: {N}` 来指定 `msg.sender` 和 `msg.value`，如下所示：

    /// #sender: account-0
    /// #value: 10
    function checkSenderIs0AndValueis10 () public payable {
        Assert.equal(msg.sender, TestsAccounts.getAccount(0), "wrong sender in checkSenderIs0AndValueis10");
        Assert.equal(msg.value, 10, "wrong value in checkSenderIs0AndValueis10");
    }
    

在单元测试插件面板中，还可以通过点击 **Generate** 按钮来自动生成测试文件。

点击 **Run** 按钮，则会开始执行单元测试了。如果存在多个文件的情况下，也可以勾选要执行哪些测试文件。

---

*Originally published on [Keegan小钢](https://paragraph.com/@keeganlee/remix)*
