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
相关推荐
前端付豪2 小时前
必知 Express和 MVC
前端·node.js·全栈
特别橙的橙汁2 小时前
Node.js 调用可执行文件时的 stdout 缓冲区问题
前端·node.js·swift
洛豳枭薰2 小时前
List梳理
数据结构·windows·list
东木月2 小时前
使用python获取Windows产品标签
开发语言·windows·python
alamhubb2 小时前
反感pnpm的全链路污染?可以了解下这个对原项目零侵入,零修改完全兼容npm的monorepo工具
前端·javascript·node.js
小范馆5 小时前
解决 Windows 11 安装时提示 “不支持 TPM 2.0” 和 “不支持安全启动” 的问题
windows·安全
还下着雨ZG5 小时前
【Window技能 01】每天自动关机:使用CMD脚本+任务计划程序实现每天定时关闭计算机
windows
洛水如云5 小时前
重塑数据管理逻辑!文件夹同步的实用指南(含工具选型 + 实操步骤)
windows·microsoft·电脑
石像鬼₧魂石6 小时前
windows系统139/tcp与445/tcp端口渗透完整流程闭环(复习总结)
windows·网络协议·tcp/ip
程序员agions6 小时前
Node.js 爬虫实战指南(三):分布式爬虫架构,让你的爬虫飞起来
分布式·爬虫·node.js