Windows下Node.js 执行Web3.js 的智能合约环境搭建

1. 安装必备软件

1.1 安装 Node.js

  1. 访问 Node.js 官网

  2. 下载 LTS 版本(建议 18.x 或以上)

  3. 安装时勾选 "Add to PATH"

  4. 验证安装:

    node --version
    npm --version

1.2 安装 Python 和构建工具

复制代码
# 安装 Windows Build Tools(以管理员身份运行 PowerShell)
npm install --global windows-build-tools

# 或单独安装 Python 2.7 或 Python 3.x
# 下载地址:https://www.python.org/downloads/
# 安装时勾选 "Add Python to PATH"

1.3 安装 Git

  1. 访问 Git 官网

  2. 下载并安装

  3. 验证安装:

    git --version

2. 创建项目并初始化

复制代码
# 创建项目文件夹
mkdir my-web3-project
cd my-web3-project

# 初始化 Node.js 项目
npm init -y

# 安装 web3.js
npm install web3

# 安装 TypeScript(可选,推荐)
npm install typescript ts-node @types/node --save-dev

3. 安装以太坊相关依赖

复制代码
# 基本依赖
npm install web3
npm install @types/web3 --save-dev  # TypeScript 类型定义

# 智能合约相关
npm install truffle --save-dev  # 开发框架
npm install @truffle/hdwallet-provider --save-dev  # 钱包提供者
npm install solc --save-dev  # Solidity 编译器

# 或使用 Hardhat(更现代)
npm install --save-dev hardhat
npx hardhat init

4. 配置 Hardhat 项目(推荐)

4.1 初始化 Hardhat

复制代码
npx hardhat init
# 选择 "Create a JavaScript project"

4.2 安装 Hardhat 插件

复制代码
npm install --save-dev @nomicfoundation/hardhat-toolbox
npm install dotenv  # 环境变量管理

4.3 配置 hardhat.config.js

复制代码
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.19",
  networks: {
    // 连接本地以太坊节点
    hardhat: {
      chainId: 1337
    },
    // 连接以太坊测试网
    sepolia: {
      url: process.env.SEPOLIA_RPC_URL || "",
      accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : []
    }
  }
};

5. 环境变量配置

创建 .env 文件:

复制代码
# 以太坊节点 RPC URL(可以使用 Infura 或 Alchemy)
INFURA_API_KEY=your_infura_api_key
ALCHEMY_API_KEY=your_alchemy_api_key
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/${INFURA_API_KEY}

# 钱包私钥(用于部署和交互)
PRIVATE_KEY=your_wallet_private_key

# 其他配置
ETHERSCAN_API_KEY=your_etherscan_api_key

6. 创建智能合约示例

创建 contracts/MyToken.sol

复制代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract MyToken {
    string public name = "MyToken";
    string public symbol = "MTK";
    uint8 public decimals = 18;
    uint256 public totalSupply = 1000000 * 10**uint256(decimals);
    
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    
    constructor() {
        balanceOf[msg.sender] = totalSupply;
    }
    
    function transfer(address to, uint256 value) public returns (bool) {
        require(balanceOf[msg.sender] >= value, "Insufficient balance");
        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;
        emit Transfer(msg.sender, to, value);
        return true;
    }
}

7. 编写 Node.js 脚本与智能合约交互

创建 scripts/interact.js

复制代码
const Web3 = require('web3');
require('dotenv').config();

async function main() {
    // 1. 连接到以太坊节点
    const web3 = new Web3(process.env.SEPOLIA_RPC_URL);
    
    // 2. 验证连接
    const networkId = await web3.eth.net.getId();
    console.log('Connected to network ID:', networkId);
    
    // 3. 获取账户信息
    const accounts = await web3.eth.getAccounts();
    console.log('Accounts:', accounts);
    
    // 4. 获取最新区块
    const latestBlock = await web3.eth.getBlockNumber();
    console.log('Latest block:', latestBlock);
    
    // 5. 获取账户余额
    const balance = await web3.eth.getBalance(accounts[0]);
    console.log('Balance:', web3.utils.fromWei(balance, 'ether'), 'ETH');
    
    // 6. 发送交易示例(需要解锁账户)
    /*
    const tx = {
        from: accounts[0],
        to: '0x...', // 接收地址
        value: web3.utils.toWei('0.01', 'ether'),
        gas: 21000
    };
    
    const receipt = await web3.eth.sendTransaction(tx);
    console.log('Transaction receipt:', receipt);
    */
}

main().catch(console.error);

8. 部署智能合约的脚本

创建 scripts/deploy.js

复制代码
const Web3 = require('web3');
const fs = require('fs');
const path = require('path');
require('dotenv').config();

async function deployContract() {
    // 初始化 Web3
    const web3 = new Web3(process.env.SEPOLIA_RPC_URL);
    
    // 加载合约 ABI 和字节码
    const contractPath = path.resolve(__dirname, '../artifacts/contracts/MyToken.sol/MyToken.json');
    const contractData = JSON.parse(fs.readFileSync(contractPath, 'utf8'));
    
    const abi = contractData.abi;
    const bytecode = contractData.bytecode;
    
    // 创建合约实例
    const contract = new web3.eth.Contract(abi);
    
    // 获取账户
    const accounts = await web3.eth.getAccounts();
    const deployer = accounts[0];
    
    console.log('Deploying contract from:', deployer);
    
    // 估算 gas
    const gasEstimate = await contract.deploy({ data: bytecode }).estimateGas({ from: deployer });
    console.log('Gas estimate:', gasEstimate);
    
    // 部署合约
    const deployedContract = await contract.deploy({ data: bytecode })
        .send({
            from: deployer,
            gas: gasEstimate,
            gasPrice: await web3.eth.getGasPrice()
        });
    
    console.log('Contract deployed at address:', deployedContract.options.address);
    
    // 保存部署地址
    const deploymentInfo = {
        networkId: await web3.eth.net.getId(),
        address: deployedContract.options.address,
        deployer: deployer,
        timestamp: new Date().toISOString()
    };
    
    fs.writeFileSync(
        path.resolve(__dirname, '../deployment.json'),
        JSON.stringify(deploymentInfo, null, 2)
    );
    
    return deployedContract;
}

deployContract().catch(console.error);

9. 测试脚本

创建 test/test-contract.js

复制代码
const { expect } = require("chai");

describe("MyToken", function() {
  it("Should deploy and have correct name", async function() {
    const [owner] = await ethers.getSigners();
    
    const MyToken = await ethers.getContractFactory("MyToken");
    const token = await MyToken.deploy();
    
    expect(await token.name()).to.equal("MyToken");
    expect(await token.symbol()).to.equal("MTK");
    expect(await token.totalSupply()).to.equal(1000000n * 10n**18n);
  });
});

10. 运行和测试

复制代码
# 编译合约
npx hardhat compile

# 运行测试
npx hardhat test

# 运行脚本
node scripts/interact.js
npx hardhat run scripts/deploy.js --network sepolia

# 启动本地开发网络
npx hardhat node

11. 常见问题和解决方案

11.1 编译问题

复制代码
# 如果遇到 C++ 编译错误
npm install --global windows-build-tools

# 或使用 WSL(Windows Subsystem for Linux)

11.2 网络连接问题

复制代码
// 使用不同的 RPC 提供商
const web3 = new Web3('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_KEY');
const web3 = new Web3('http://localhost:8545');  // 本地节点

11.3 内存不足

复制代码
# 增加 Node.js 内存限制
set NODE_OPTIONS=--max-old-space-size=4096

12. 推荐的开发工具

  1. 编辑器: VS Code(安装 Solidity 插件)
  2. 以太坊钱包: MetaMask 浏览器扩展
  3. 测试网 ETH : 从 Sepolia Faucet 获取
  4. 区块链浏览器 : Etherscan
相关推荐
程序员徐师兄5 小时前
Windows JDK11 下载安装教程,适合新手
java·windows·jdk11 下载安装·jdk11 下载教程
编码者卢布8 小时前
【App Service】Java应用上传文件功能部署在App Service Windows上报错 413 Payload Too Large
java·开发语言·windows
多来哈米10 小时前
openclaw在Windows部署
windows·openclaw
视觉AI10 小时前
【踩坑实录】Windows ICS 共享网络下,国产化盒子 SSH 连接异常的完整分析
网络·windows·ssh
qq_2466461914 小时前
openclaw快速安装-windows版
windows·stm32·单片机
sonrisa_15 小时前
Python同一类不同方法中变量值的传递
开发语言·windows·python
玖釉-15 小时前
探索连续细节层次(Continuous LOD):深入解析 NVIDIA 的 nv_cluster_lod_builder
c++·windows·图形渲染
MyY_DO15 小时前
第九课ida与花指令
windows·od
多多*16 小时前
Mysql数据库相关 事务 MVCC与锁的爱恨情仇 锁的层次架构 InnoDB锁分析
java·数据库·windows·sql·oracle·面试·哈希算法
LateFrames16 小时前
“蚯蚓涌动” 的屏保: DirectX 12 + ComputeSharp + Win32
windows·ui·gpu算力