:2026-03-13 4:39 点击:1
以太坊,作为全球领先的智能合约平台,为去中心化应用(DApp)的开发提供了坚实的基础,而 Node.js,凭借其异步、事件驱动的特性以及庞大的 npm 生态系统,成为了与以太坊区块链进行交互、构建 DApp 后端逻辑和工具链的理想选择,本文将深入探讨如何使用 Node.js 编写以太坊相关的代码,涵盖从环境搭建到智能合约交互的核心步骤。
在开始编码之前,理解 Node.js 在以太坊生态中的优势至关重要:
web3.js, ethers.js),简化了与以太坊节点、钱包、智能合约的交互。在编写 Node.js 以太坊代码之前,需要准备以下环境:
与以太坊交互,离不开核心库,目前最主流的是 web3.js 和 ethers.js。
以下示例将以 ethers.js 为例,因其更现代的特性和开发者友好的 API。
mkdir my-dapp cd my-dapp npm init -y npm install ethers
const { ethers } = require("ethers");
// 替换为你的 Infura/Alchemy 节点 URL 或 Ganache RPC URL
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); // Ganache 默认
// const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_PROJECT_ID");
// 获取当前区块号
provider.getBlockNumber().then((blockNumber) => {
console.log("当前区块号:", blockNumber);
}).catch(console.error);
// 获取账户余额
const address = "0xYourAddressHere"; // 替换为以太坊地址
provider.getBalance(address).then((balance) => {
console.log(`地址 ${address} 的余额:`, ethers.utils.formatEther(balance), "ETH");
}).catch(console.error);
你需要一个简单的

SimpleStorage.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
编译合约:
可以使用 solc-js 命令行工具或 Truffle/Hardhat 框架,这里以 solc-js 为例(需先安装:npm install solc)。
部署合约(使用 Node.js 和 ethers.js):
const { ethers } = require("ethers");
const fs = require("fs");
const solc = require("solc");
// 1. 编译合约
const sourceCode = fs.readFileSync("SimpleStorage.sol", "utf8");
const input = {
language: "Solidity",
sources: {
"SimpleStorage.sol": {
content: sourceCode
}
},
settings: {
outputSelection: {
"*": {
"*": ["*"]
}
}
}
};
const compiledOutput = JSON.parse(solc.compile(JSON.stringify(input)));
const contractInterface = compiledOutput.contracts["SimpleStorage.sol"]["SimpleStorage"].abi;
const bytecode = compiledOutput.contracts["SimpleStorage.sol"]["SimpleStorage"].evm.bytecode.object;
// 2. 连接节点和钱包
// 使用 Ganache 提供的测试账户私钥
const privateKey = "0xYourTestAccountPrivateKeyHere"; // 替换为 Ganache 中的私钥
const wallet = new ethers.Wallet(privateKey, provider);
console.log("部署者地址:", wallet.address);
// 3. 部署合约
const factory = new ethers.ContractFactory(contractInterface, bytecode, wallet);
const contract = await factory.deploy(); // 部署合约,返回 Contract 对象
console.log("合约部署中,交易哈希:", contract.deployTransaction.hash);
// 等待合约部署确认
await contract.deployed();
console.log("合约部署成功,地址:", contract.address);
假设合约已部署,我们可以读取和调用其函数。
// 合约地址(从部署结果获取或已知)
const contractAddress = "0xYourDeployedContractAddressHere";
// 合约 ABI (从编译输出获取或已知)
const contractABI = [ /* 这里粘贴 SimpleStorage 的 ABI */ ]; // 为了简洁,省略具体 ABI 内容
// 创建合约实例
const contract = new ethers.Contract(contractAddress, contractABI, provider); // 使用 provider 只读
// const contractWithSigner = new ethers.Contract(contractAddress, contractABI, wallet); // 使用 wallet 可写
// 读取合约状态(调用 view/pure 函数)
const currentValue = await contract.get();
console.log("当前存储的值:", currentValue.toString());
// 调用合约状态修改函数(需要签名)
const setTx = await contractWithSigner.set(42); // 调用 set 函数,参数为 42
console.log("交易发送中,哈希:", setTx.hash);
await setTx.wait(); // 等待交易确认
console.log("交易确认成功!");
// 再次读取验证
const newValue = await contract.get();
console.log("修改后的值:", newValue.toString());
contract.on("ValueChanged", (newValue, event) => {
console.log("监听到 ValueChanged 事件,新值:", newValue.toString());
});
本文由用户投稿上传,若侵权请提供版权资料并联系删除!