4. 执行环境搭建:Node.js与Hardhat环境、Web3.js与Ethers.js库、RPC节点配置

好,咱们直接进入正题。套利策略写得再漂亮,跑不起来等于零。这一章,我就带你搭一套真正能用的执行环境。

说实话,我见过太多人卡在环境搭建这一步。不是版本冲突,就是RPC连不上。我自己早期做套利机器人时,光配环境就折腾了两天。后来总结出一套「稳如老狗」的流程,今天全部分享给你。

4.1 Node.js 环境安装

Node.js 是整个套利脚本的运行基石。你写的所有代码,最终都要靠它来执行。

版本选择:我个人建议用 LTS 版本,别追新。我踩过坑——有次用了 Node 18 的测试版,结果某个依赖包死活装不上,查了半天才发现是兼容性问题。

推荐版本:Node.js 16.x 或 18.x LTS

安装方式:

  • Windows/Mac:直接官网下载安装包
  • Linux:用 nvm 管理版本,方便切换
# 安装 nvm(Linux/Mac)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

# 安装 Node 16 LTS
nvm install 16
nvm use 16

# 验证版本
node -v   # 输出 v16.20.0 或类似
npm -v    # 输出 8.x.x

小技巧:装完 Node 后,建议把 npm 源换成淘宝镜像。国内下载依赖包快很多。

npm config set registry https://registry.npmmirror.com

4.2 Hardhat 开发框架

Hardhat 是我最常用的以太坊开发框架。为什么选它?因为它在本地模拟链上跑得飞快,调试起来特别方便。

我记得第一次用 Truffle 时,每次改代码都要重新编译部署,等得人抓狂。Hardhat 的「console.log」调试功能简直是救星——你可以在合约代码里直接打印变量,就像写 JavaScript 一样自然。

4.2.1 初始化 Hardhat 项目

# 创建项目目录
mkdir arbitrage-bot
cd arbitrage-bot

# 初始化 npm 项目
npm init -y

# 安装 Hardhat
npm install --save-dev hardhat

# 初始化 Hardhat 项目
npx hardhat init

初始化时,选择「Create a JavaScript project」。它会自动帮你生成目录结构:

arbitrage-bot/
├── contracts/        # 智能合约存放目录
├── scripts/          # 部署和交互脚本
├── test/             # 测试文件
├── hardhat.config.js # 配置文件
└── package.json      # 依赖管理

4.2.2 配置 Hardhat

打开 hardhat.config.js,这是整个项目的核心配置。我一般会这样配:

require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: "0.8.19",
  networks: {
    hardhat: {
      // 本地网络,默认配置
    },
    sepolia: {
      url: "https://sepolia.infura.io/v3/YOUR_PROJECT_ID",
      accounts: ["你的私钥"]
    },
    mainnet: {
      url: "https://mainnet.infura.io/v3/YOUR_PROJECT_ID",
      accounts: ["你的私钥"]
    }
  }
};

⚠️ 安全警告:千万别把私钥直接写在配置文件里!我早期犯过这个错,代码传到 GitHub 上,几分钟内钱包就被清空了。建议用环境变量:

// 使用 dotenv 加载 .env 文件
require("dotenv").config();

module.exports = {
  networks: {
    mainnet: {
      url: process.env.MAINNET_RPC_URL,
      accounts: [process.env.PRIVATE_KEY]
    }
  }
};

4.3 Web3.js 与 Ethers.js 库

这两个库都是用来和以太坊交互的。简单说,它们帮你「翻译」JavaScript 和区块链之间的对话。

特性 Web3.js Ethers.js
体积 较大(~400KB) 较小(~200KB)
TypeScript 支持 一般 原生支持
ENS 解析 需额外配置 内置支持
Gas 估算 手动调用 自动估算
社区活跃度 极高

我个人更推荐 Ethers.js。为什么?因为它的 API 设计更现代,用起来更顺手。举个例子,查询账户余额:

// Web3.js 方式
const balance = await web3.eth.getBalance(address);
const etherBalance = web3.utils.fromWei(balance, 'ether');

// Ethers.js 方式
const balance = await provider.getBalance(address);
const etherBalance = ethers.utils.formatEther(balance);

你看,Ethers.js 的命名更直观。而且它内置了 gas 估算,省去不少麻烦。

4.3.1 安装与使用

# 安装 Ethers.js
npm install ethers

# 安装 Web3.js(如果你坚持要用)
npm install web3

写套利脚本时,我通常这样初始化:

const { ethers } = require("ethers");

// 连接到以太坊节点
const provider = new ethers.providers.JsonRpcProvider(
  "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
);

// 创建钱包对象(用于发送交易)
const wallet = new ethers.Wallet("你的私钥", provider);

// 连接到合约
const contract = new ethers.Contract(
  "合约地址",
  ["function balanceOf(address) view returns (uint256)"],
  wallet
);

经验之谈:做套利时,建议把 provider 和 wallet 分开。provider 只负责读数据,wallet 负责写交易。这样万一私钥泄露,也只是写权限受影响,读数据不受影响。

4.4 RPC 节点配置

RPC 节点就是你和区块链之间的桥梁。节点选得好不好,直接决定你的套利机器人能不能抢到机会。

我早期用公共节点做套利,结果经常遇到限流。有一次眼睁睁看着一个 2 ETH 的套利机会从眼前溜走,就是因为节点返回数据太慢。从那以后,我学乖了——套利用的节点,必须自己搭或者买付费服务。

4.4.1 节点类型对比

类型 延迟 稳定性 费用 推荐场景
公共节点(Infura/Alchemy 免费版) 高(100-500ms) 一般 免费 开发测试
付费节点(Infura/Alchemy 付费版) 低(20-50ms) 月费 $50-$500 小规模套利
自建节点(Geth/Nethermind) 极低(5-20ms) 极高 服务器成本 高频套利
Flashbots 节点 极低 极高 按交易收费 MEV 套利

4.4.2 配置多个节点做冗余

做套利最怕节点挂掉。我一般会配 3 个节点做 failover:

const providers = [
  new ethers.providers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/KEY1"),
  new ethers.providers.JsonRpcProvider("https://eth-mainnet.infura.io/v3/KEY2"),
  new ethers.providers.JsonRpcProvider("https://rpc.ankr.com/eth")
];

// 轮询使用,哪个快用哪个
async function getFastestProvider() {
  const results = await Promise.race(
    providers.map(async (provider) => {
      const start = Date.now();
      await provider.getBlockNumber();
      return { provider, latency: Date.now() - start };
    })
  );
  return results.provider;
}

⚠️ 注意:不同节点的数据可能有短暂的不一致。特别是刚出块那几秒,有的节点已经同步了,有的还没。做套利时,建议用同一个节点读取和发送交易,避免数据不一致导致交易失败。

4.5 完整环境搭建流程

好,咱们把上面所有东西串起来。这是我每次搭建新环境的标准流程:

  1. 安装 Node.js(LTS 版本,用 nvm 管理)
  2. 创建项目目录,初始化 npm
  3. 安装 Hardhat 并初始化项目
  4. 安装 Ethers.js 和 dotenv
  5. 配置 RPC 节点(至少 2 个,做冗余)
  6. 编写测试脚本,验证连接是否正常

验证脚本长这样:

// test-connection.js
const { ethers } = require("ethers");
require("dotenv").config();

async function main() {
  const provider = new ethers.providers.JsonRpcProvider(
    process.env.MAINNET_RPC_URL
  );
  
  const blockNumber = await provider.getBlockNumber();
  console.log(`当前区块高度: ${blockNumber}`);
  
  const gasPrice = await provider.getGasPrice();
  console.log(`当前 Gas 价格: ${ethers.utils.formatUnits(gasPrice, "gwei")} Gwei`);
  
  console.log("✅ 环境搭建成功!");
}

main().catch(console.error);

跑一下:node test-connection.js。如果看到区块高度和 Gas 价格,说明环境搭好了。

核心要点总结:

  • Node.js 用 LTS 版本,别追新
  • Hardhat 是本地开发和测试的首选
  • Ethers.js 比 Web3.js 更适合套利场景
  • RPC 节点必须做冗余,别把所有鸡蛋放一个篮子里
  • 私钥永远不要硬编码,用环境变量

环境搭好了,下一步就是写真正的套利逻辑了。不过在那之前,我建议你先跑几个测试交易,确保整个链路是通的。别问我为什么知道——我曾经花了一整天调试一个「套利策略」,最后发现是 RPC 节点配错了,压根没连上主网。

执行环境搭建架构图 Node.js 运行环境 Hardhat 开发框架 合约编译 本地测试链 脚本部署 Web3.js / Ethers.js 交互库 合约调用 交易签名 事件监听 RPC 节点(Infura / Alchemy / 自建) 运行环境基础 开发与测试框架 链上交互接口 区块链数据入口

专注资料整理