---
title: "什么是 Solidity 编译器？"
description: "了解 Solidity 编译器的工作原理及使用方法"
---

# 什么是 Solidity 编译器？

Ethereum 开发者[使用 Solidity 编写智能合约](https://docs.soliditylang.org/en/v0.8.16/using-the-compiler.html#compiler-tools)时，必须将代码通过编译器处理，这样 **Ethereum Virtual Machine（EVM）** 才能理解并执行相应的指令。[Solidity](https://www.alchemy.com/overviews/solidity) 编译器将代码转换为一组字节指令。

Solidity 是 Ethereum（按市值计算的第二大加密货币）的编程语言。Solidity 是一种专为实现智能合约而创建的高级编程语言。此外，Solidity 是一种面向合约、面向对象且采用静态类型的语言。

本文将介绍 Solidity 编译器、如何安装 Solidity 编译器、Solidity 编译工具，以及一些公开可用的反编译器。

## **什么是 Solidity 编译器？**

Solidity 编译器有两种：**solc** 和由 solc 衍生出的 **solc.js**。真正的 Solidity 编译器 solc 是用 C++ 编写的，在本文撰写时版本为 0.8.16。solc.js 使用 Emscripten 将 C++ 代码编译为 JavaScript。每个版本的 solc 都会被编译成对应的 JavaScript 版本。

Solidity 文件通过名为 solcjs 的 Node.js 库和命令行工具进行编译组装。它仅使用 JavaScript 进行编译，而不依赖 solc 命令行编译器，因此比 solc 更容易安装。

在部署智能合约之前，必须先将其编译为 [EVM（Ethereum Virtual Machine）](https://www.alchemy.com/overviews/what-is-the-ethereum-virtual-machine-evm)可识别的字节码。字节码是 Solidity 代码"翻译"后得到的信息，其中包含二进制计算机指令。

在 Ethereum 中，部署到区块链上的正是这些字节码。编译过程还会生成 [ABI（Application Binary Interface）](https://www.alchemy.com/overviews/solidity-abi)，它是两个程序模块之间的接口，通常用于操作系统与用户程序之间。

<ImageBlock
  src="https://media.alchemy.com/1704186026-solidity-compiler.png"
  alt="Solidity 编译器将源代码转换为 bytecode 和 ABI 的示意图"
  width={456}
  height={414}
  caption="Solidity 编译器 - 来源：Intellipat"
/>

合约被编译为字节码后在 EVM 上执行。这些字节码会被部署到区块链，并保存在某个地址上，之后公开供任何人调用。地址标识了一个已部署的合约实例，该实例同时保存着用于维护合约内部状态的持久化存储。Ether 是 Ethereum 的原生加密货币，既可作为价值存储手段，也用于支付在区块链上执行智能合约的费用，同时还是对维护 Ethereum 网络安全的矿工的奖励。

下面是一个合约编译过程的简单示例。

我们将使用 Remix（一款[常用的在线 Ethereum IDE](https://www.alchemy.com/overviews/solidity-ide)）来编译这段代码，这样就无需在本地机器上安装任何工具。

从下图可以看到，图片底部的粉色和紫色箭头分别指向 ABI 和字节码。ABI 以 JSON 格式表示。

<ImageBlock
  src="https://media.alchemy.com/1704186197-solidity-compiler-abi-bytecode.jpg"
  alt="Remix IDE 编译面板，箭头指向 ABI 和 bytecode 输出"
  width={730}
  height={1252}
  caption="ABI 和 Bytecode 已生成。"
/>

## **如何安装 Solidity 编译器**

在[学习 Solidity](https://www.alchemy.com/overviews/learn-solidity) 的过程中，你可能需要安装 Solidity 编译器。安装 Solidity 编译器有多种便捷方式。一种简单的方法是使用 Remix，它可以在线使用。不过，这种方式适合小型合约，编译选项也比较有限。

对于较大的合约，可以通过 npm/Node.js、Docker、Linux、MacOS 软件包或静态二进制文件来安装 Solidity 编译器。

### **方法一：使用 npm/node.js 安装**

Solidity 编译器（即 solc）可以通过 npm 安装。以下命令将安装 solcjs 程序，并使其在整个系统中可用。

现在可以运行以下命令来测试你的 Solidity 编译器。

现在你已经可以使用 solcjs 了，它的功能比标准 Solidity 编译器少，但可以作为一个不错的起点。

### **方法二：使用 Docker 安装**

要开始 Solidity 编程，可以下载并使用 Docker 镜像。由于 Docker 镜像运行的是编译器可执行文件，你可以向其传递任意编译器参数。

拉取 Solidity Docker 镜像的命令如下。

下载 Docker 镜像后，运行以下命令进行验证。

要在宿主机上使用 Docker 镜像编译 Solidity 文件，需要挂载一个本地文件夹用于输入输出，并指定要编译的合约。

### **方法三：使用二进制软件包安装（MacOS、Linux）**

#### MacOS 安装

我们可以使用 Homebrew 在 MacOS 上安装 Solidity。它提供了从源码构建的 macOS 软件包，我们只需按照安装说明操作即可。

执行完成后，可以运行以下命令来验证 Solidity 是否安装成功。

你应该会得到类似这样的输出：

<ImageBlock
  src="https://media.alchemy.com/1704186340-macos-solidity-installation.png"
  alt="终端输出，验证 macOS 上 Solidity 编译器安装成功"
  width={1116}
  height={128}
  caption="macOS 安装 Solidity"
/>

#### Linux 安装

安装 Linux 软件包的过程非常简单，只需几个步骤即可完成。首先，将该仓库添加到我们的仓库列表中。

然后更新软件包列表并安装 solc。如果想使用每日构建版本而非最新的稳定版本，应将仓库条目改为 ethereum/ethereum-dev。

## 编译一个示例 Solidity 智能合约

以下代码使用了我们上面提供的示例合约。

要编译合约，可以运行以下代码。

要使用特定的 EVM 版本来编译合约，可以按如下方式设置版本。

### **什么是 Solidity-upgrade？**

**solidity-upgrade 可以帮助你升级合约，以适应语言的破坏性变更。** 虽然它无法为每一次破坏性发布都做出所有必要的调整，但它支持其中一部分调整，而这些调整原本需要大量繁琐的手动操作。

### Solidity-upgrade 是如何工作的？

Solidity-upgrade 基于 _libsolidity_，能够解析、编译并分析你的源文件，从而找出可应用的源码升级方案。源码升级被视为对源代码的小幅文本改动，这些改动会应用于所提供源文件的内存副本上。

升级过程分为两个阶段：

#### **第一阶段**

首先，由于在解析源文件的这一层级无法对源代码进行升级，因此会收集错误信息，并可以通过 —verbose 标志将其记录下来。目前尚无可用的源码升级方案。

#### **第二阶段**

在第二阶段，所有源文件会被编译，同时所有已启用的升级分析模块会与编译过程一同运行。默认情况下，所有可用模块都会被启用。

solidity-upgrade 可能会发现一些编译问题，而源码升级方案有可能修复这些问题。如果没有问题，就不会报告任何源码升级方案，此时任务即告完成。如果出现问题，且某个[升级模块](https://docs.soliditylang.org/en/v0.8.16/using-the-compiler.html#compiler-tools)报告了源码升级方案，则会应用第一个被报告的源码升级方案，并对所有提供的源文件重新触发编译。

## **什么是 Solidity 反编译器？**

**Solidity 反编译器是一种工具，它以已编译的智能合约 EVM 代码作为输入，将其反编译为类似 Solidity 的源代码。** 该反编译器有助于验证和理解合约的行为。

在原始代码不可用的情况下，Solidity 反编译器在调试智能合约时非常有用。不过，反编译 EVM 字节码的技术仍在发展中，目前一些可用的反编译器只能对复杂合约进行部分反编译，反编译后的版本中往往会缺失大量底层代码。

### **Ethereum virtual machine（EVM）反编译器**

以下是一些常用的 Solidity 反编译器：

#### **1. Ethervm.io**

[Ethervm.io](https://www.alchemy.com/dapps/ethervm-decompiler) 是一款免费的在线反编译器，可以将 Ethereum 合约字节码反编译为更易读的、类似 Solidity 的代码。

**开始使用：** [https://ethervm.io/decompile](https://www.ethervm.io/decompile)

#### **2. JEB decompiler**

JEB decompiler 提供了一些特定功能，例如在没有 ABI 的情况下通过代码分析来确定方法。JEB 已成为安全审计人员、漏洞研究人员以及逆向工程师调查 Ethereum 平台上不透明智能合约时的首选工具。

开始使用：[https://www.pnfsoftware.com/jeb/manual/ethereum/](https://etherscan.io/bytecode-decompiler)

#### 3. Etherscan 在线反编译器

[Etherscan 在线反编译器](https://etherscan.io/bytecode-decompiler)是一款针对 Ethereum Virtual Machine（EVM）的反编译器，它能从运行时字节码中提取信息，并以更易读的形式呈现出来。

#### **4. Nick Johnson 开发的 Evemedis**

Evemedis 是一款 EVM 反汇编器。它对字节码执行静态分析，从而提供比原始 EVM 操作更高层次的抽象。

开始使用：[https://github.com/Arachnid/evmdis](https://github.com/Arachnid/evmdis)

#### **5. Decurity**

Decurity 是一款 ABI 反编译器，实现了用于恢复 EVM 智能合约 ABI（包括函数名）的简单工具。

开始使用：[https://github.com/Decurity/abi-decompiler](https://github.com/Decurity/abi-decompiler)

## **总结**

现在你已经了解了什么是 Solidity 编译器、如何安装它们，以及如何编译一个简单的合约。Solidity 官方文档中还包含更多关于 Solidity 编译器的信息。

如果你正[刚开始学习 Solidity](https://www.alchemy.com/overviews/learn-solidity)，可以报名参加 Alchemy University 为期 7 周的 Solidity 开发者训练营，通过免费、互动且内容全面的在线课程来[掌握 Ethereum 开发的基础知识](https://www.alchemy.com/university/courses/ethereum?a=8e8f08e668)。如果开发者对开发本身还比较陌生，Alchemy University 的[**3 周 JavaScript 速成课程**](https://www.alchemy.com/university/courses/js?a=8e8f08e668)是开始 Ethereum 训练营之前一个很好的先修课程。如果你已经掌握了基础知识，想要深入学习，可以了解一下 [Alchemy 全新的 Solidity 课程](https://www.alchemy.com/university/courses/solidity?a=8e8f08e668)。
