ZBLOG

编译geth可执行文件,默认会生成在当前目录

从零开始:深入以太坊源码编译全指南**


以太坊作为全球领先的智能合约平台和去中心化应用(DApps)的基础,其源码的开放性为开发者和研究者提供了宝贵的学习和探索机会,编译以太坊源码不仅是理解其底层工作机制的关键一步,也是进行二次开发、提交贡献或进行安全审计的基础,本文将详细指导您如何从零开始编译以太坊(以Go客户端geth为例)的源码,涵盖环境准备、依赖安装、编译过程及常见问题解决。

为什么需要编译以太坊源码?

在开始之前,我们先明确一下编译以太坊源码的目的:

  1. 深度学习:通过阅读和调试编译后的代码,深入理解以太坊的共识机制(如Ethash/Clique)、网络协议、虚拟机(EVM)实现、状态管理核心概念。
  2. 功能定制:根据项目需求,对以太坊客户端进行修改或功能扩展,例如定制共识算法、添加新的RPC接口等。
  3. 贡献代码:如果您希望向以太坊开源社区(如geth)贡献代码,需要先在自己的环境中编译和测试您的修改。
  4. 调试与审计:在进行安全审计或特定问题调试时,编译源码并添加调试信息是必要步骤。
  5. 获取最新版本:直接从GitHub克隆最新源码编译,可以获得比官方发布版本更及时的功能更新和错误修复。

编译前的准备工作

在开始编译之前,确保您的系统环境满足以下要求,本文主要以Linux和macOS系统为例进行说明,Windows用户可以通过WSL2(Windows Subsystem for Linux 2)来获得接近Linux的体验。

系统要求

  • 操作系统:Linux (推荐Ubuntu 18.04/20.04/22.04 LTS)、macOS (10.14+) 或 Windows (通过WSL2)。
  • 硬件
    • CPU:x86_64架构,多核CPU能显著加快编译速度。
    • 内存:至少8GB,推荐16GB或以上,因为编译过程会占用较多内存。
    • 存储空间:至少20GB可用空间,用于存放源码、依赖和编译产物。
  • 网络:稳定的网络连接,用于下载Go工具链和其他依赖库。

安装必要工具

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install -y build-essential git libsnappy-dev zlib1g-dev libgflags-dev libncurses5-dev libncursesw5-dev pkg-config cmake

macOS

使用Homebrew安装必要的工具:

brew install git cmake snappy

Windows (WSL2)

在WSL2的Ubuntu环境中,参考Linux (Ubuntu/Debian)的命令安装。

安装Go语言环境

以太坊的Go客户端(如geth)主要使用Go语言编写,因此需要安装Go编译环境。

  • 下载Go:访问Go官方下载页面,选择适合您系统的最新稳定版本(例如1.21.x)。

  • 安装Go (以Linux为例):

    # 下载Go二进制包 (请替换为最新版本号)
    wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz
    # 解压到/usr/local (需要sudo权限)
    sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
  • 配置环境变量

    编辑~/.bashrc~/.profile文件(根据您使用的shell):

    nano ~/.bashrc

    添加以下行:

    export PATH=$PATH:/usr/local/go/bin
    export GOPATH=$HOME/go
    export PATH=$PATH:$GOPATH/bin

    保存后,执行以下命令使配置生效:

    source ~/.bashrc
  • 验证Go安装

    go version

    应该显示安装的Go版本号。

获取以太坊源码

以太坊的主要Go客户端geth的源码托管在GitHub上。

  1. 安装Git (如果尚未安装):

    • Linux: sudo apt install git
    • macOS: brew install git
  2. 克隆geth仓库

    # 创建一个目录用于存放以太坊相关代码
    mkdir -p ~/ethereum-code
    cd ~/ethereum-code
    # 克隆geth官方仓库
    git clone https://github.com/ethereum/go-ethereum.git
  3. 切换到特定版本(可选): 如果您需要编译特定版本的geth(例如最新稳定版),可以切换到对应的tag:

    cd go-ethereum
    # 查看所有可用tag
    git tag --list | sort -V | tail -n 10
    # 切换到特定tag,例如v1.13.6
    git checkout v1.13.6

编译以太坊源码

进入源码目录

cd ~/ethereum-code/go-ethereum

编译geth

以太坊源码使用Go的go build命令进行编译,最简单的方式是:

 

或者直接使用go build

# 编译geth
go build -o geth ./cmd/geth
# 编译其他工具,如erigon (另一个以太坊客户端,如果克隆的是erigon仓库)、abigen、evm等
# go build -o abigen ./cmd/abigen
# go build -o evm ./cmd/evm

make geth命令会自动处理一些依赖和编译选项,推荐使用。

编译成功后,您会在当前目录(或./build/bin目录,取决于Makefile配置)下看到geth可执行文件。

验证编译结果

./geth version

如果显示出版本信息、commit hash等,说明编译成功。

编译过程中的常见问题与解决方法

  1. Go版本不兼容

    • 问题:提示Go版本过高或过低。
    • 解决:确保安装的Go版本与以太坊源码要求的版本兼容,可以查看go-ethereum仓库的README.mdgo.mod文件中推荐的Go版本,如果版本不匹配,请卸载当前Go并安装正确版本。
  2. 依赖库缺失或版本问题

    • 问题:编译时提示某些系统库(如libsnappy、zlib)找不到或版本不正确。
    • 解决:确保在“准备阶段”已经安装了所有必要的系统依赖库,可以尝试更新包管理器缓存后重新安装。
  3. 内存不足

    • 问题:编译过程中系统卡顿或编译失败,提示out of memory。
    • 解决:增加系统虚拟内存,或者关闭占用内存较大的应用程序,如果有条件,增加物理内存是最直接的解决方法。
  4. 网络问题导致依赖下载失败

    • 问题go build过程中下载Go模块失败。
    • 解决:检查网络连接是否稳定,可以尝试配置Go代理(如国内用户可配置:export GOPROXY=https://goproxy.cn,direct)。
  5. 编译错误(代码层面)

    • 问题:提示语法错误、类型错误等。
    • 解决
      • 确保是从官方仓库克隆的最新或稳定版本源码。
      • 检查是否在正确的目录下执行编译命令。
      • 尝试清理编译缓存后重新编译:go clean -cache,然后重新make gethgo build
      • 如果是自己修改的代码,仔细检查修改部分是否有误。

编译后做什么?

编译成功只是第一步,接下来您可以:

  1. 运行geth节点

    # 初始化节点(首次运行需要)
    ./geth init --datadir ~/.ethereum ~/genesis.json (需要准备genesis.json文件)
    # 启动全节点
    ./geth --datadir ~/.ethereum --syncmode full --gcmode full
  2. 阅读源码:使用IDE(如GoLand、VS Code + Go插件)打开源码,进行阅读和调试。

  3. 运行测试用例

    # 运行所有测试
    make test
    # 运行特定
分享:
扫描分享到社交APP