Web3 开发者入门完全指南:从零构建你的第一个 DApp
想进入 Web3 开发但不知道从哪开始?这篇指南带你从零搭建开发环境,写第一个智能合约,部署到测试网,并用前端连接它。
为什么学 Web3 开发?
- 💰 Web3 开发者薪资普遍高于传统开发者
- 🌍 去中心化应用正在重塑金融、游戏、社交
- 🔧 工具链已经成熟,入门门槛大幅降低
- 📈 2026 年 Web3 岗位需求持续增长
1. 开发环境搭建
1.1 安装 Node.js
# 使用 nvm 安装(推荐)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 18
nvm use 18
# 验证
node --version # v18.x.x
npm --version # 9.x.x
1.2 安装开发框架
Hardhat(推荐新手):
mkdir my-first-dapp && cd my-first-dapp
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init
选择 "Create a JavaScript project",其余默认即可。
项目结构:
my-first-dapp/
├── contracts/ # 智能合约
├── scripts/ # 部署脚本
├── test/ # 测试文件
├── hardhat.config.js # 配置文件
└── package.json
1.3 安装 MetaMask
- 访问 https://metamask.io
- 安装浏览器扩展
- 创建钱包(保管好助记词!)
- 添加 Sepolia 测试网
2. Solidity 基础
Solidity 是以太坊的智能合约语言,语法类似 JavaScript。
2.1 Hello World 合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract HelloWorld {
string public greeting;
address public owner;
constructor() {
greeting = "Hello, Web3!";
owner = msg.sender;
}
function setGreeting(string memory _greeting) public {
require(msg.sender == owner, "Only owner can change greeting");
greeting = _greeting;
}
function getGreeting() public view returns (string memory) {
return greeting;
}
}
2.2 核心概念
| 概念 | 说明 |
|---|---|
pragma |
指定编译器版本 |
contract |
类似 class,是合约的基本单位 |
public |
自动生成 getter 函数 |
view |
只读函数,不修改状态 |
msg.sender |
调用者的地址 |
constructor |
部署时执行一次 |
2.3 数据类型
// 基础类型
uint256 public number = 42; // 无符号整数
bool public active = true; // 布尔值
address public addr; // 以太坊地址
string public name = "FlowForge"; // 字符串
// 映射(类似字典)
mapping(address => uint256) public balances;
// 数组
uint256[] public numbers;
3. 编写第一个完整合约
让我们创建一个简单的投票合约:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SimpleVoting {
// 数据结构
struct Proposal {
string name;
uint256 voteCount;
}
// 状态变量
address public chairperson;
mapping(address => bool) public hasVoted;
Proposal[] public proposals;
// 事件
event Voted(address indexed voter, uint256 proposalIndex);
// 构造函数
constructor(string[] memory proposalNames) {
chairperson = msg.sender;
for (uint256 i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
// 投票函数
function vote(uint256 proposalIndex) public {
require(!hasVoted[msg.sender], "Already voted");
require(proposalIndex < proposals.length, "Invalid proposal");
hasVoted[msg.sender] = true;
proposals[proposalIndex].voteCount++;
emit Voted(msg.sender, proposalIndex);
}
// 获取提案数量
function getProposalCount() public view returns (uint256) {
return proposals.length;
}
// 获取提案信息
function getProposal(uint256 index) public view returns (string memory name, uint256 voteCount) {
require(index < proposals.length, "Invalid index");
Proposal storage p = proposals[index];
return (p.name, p.voteCount);
}
}
4. 编写测试
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("SimpleVoting", function () {
let voting;
let owner, voter1, voter2;
beforeEach(async function () {
[owner, voter1, voter2] = await ethers.getSigners();
const SimpleVoting = await ethers.getContractFactory("SimpleVoting");
voting = await SimpleVoting.deploy(["Alice", "Bob", "Charlie"]);
});
it("Should initialize proposals", async function () {
expect(await voting.getProposalCount()).to.equal(3);
const [name, votes] = await voting.getProposal(0);
expect(name).to.equal("Alice");
expect(votes).to.equal(0);
});
it("Should allow voting", async function () {
await voting.connect(voter1).vote(0);
const [, votes] = await voting.getProposal(0);
expect(votes).to.equal(1);
});
it("Should prevent double voting", async function () {
await voting.connect(voter1).vote(0);
await expect(voting.connect(voter1).vote(1)).to.be.revertedWith("Already voted");
});
});
运行测试:
npx hardhat test
5. 部署到测试网
5.1 配置 Sepolia 网络
// hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.20",
networks: {
sepolia: {
url: "https://ethereum-sepolia-rpc.publicnode.com",
accounts: ["YOUR_PRIVATE_KEY"] // MetaMask 导出的私钥
}
}
};
5.2 编写部署脚本
// scripts/deploy.js
const hre = require("hardhat");
async function main() {
const SimpleVoting = await hre.ethers.getContractFactory("SimpleVoting");
const voting = await SimpleVoting.deploy(["Alice", "Bob", "Charlie"]);
await voting.waitForDeployment();
console.log("SimpleVoting deployed to:", await voting.getAddress());
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
5.3 执行部署
# 确保钱包有测试 ETH
npx hardhat run scripts/deploy.js --network sepolia
6. 前端连接钱包
6.1 安装 ethers.js
npm install ethers
6.2 连接 MetaMask
import { ethers } from "ethers";
// 连接钱包
async function connectWallet() {
if (typeof window.ethereum === "undefined") {
alert("请安装 MetaMask!");
return;
}
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
console.log("连接成功:", address);
return { provider, signer };
}
6.3 与合约交互
// 合约 ABI(编译后生成)
const CONTRACT_ABI = [...]; // 从 artifacts/contracts/SimpleVoting.sol/SimpleVoting.json 复制
const CONTRACT_ADDRESS = "0x..."; // 部署后的合约地址
async function vote(proposalIndex) {
const { signer } = await connectWallet();
const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, signer);
const tx = await contract.vote(proposalIndex);
await tx.wait();
console.log("投票成功!");
}
async function getProposals() {
const { provider } = await connectWallet();
const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider);
const count = await contract.getProposalCount();
const proposals = [];
for (let i = 0; i < count; i++) {
const [name, votes] = await contract.getProposal(i);
proposals.push({ name, votes: Number(votes) });
}
return proposals;
}
7. 安全最佳实践
7.1 常见漏洞
| 漏洞 | 说明 | 防御 |
|---|---|---|
| 重入攻击 | 外部调用中重复进入函数 | 使用 ReentrancyGuard |
| 整数溢出 | 数值超出范围 | Solidity 0.8+ 自动检查 |
| 权限漏洞 | 未限制关键函数 | 使用 modifier 验证 |
| 前端攻击 | 用户签署恶意交易 | 验证交易参数 |
7.2 安全检查清单
- [ ] 使用最新 Solidity 版本
- [ ] 所有外部调用放在最后
- [ ] 关键函数添加权限控制
- [ ] 使用 OpenZeppelin 库
- [ ] 充分测试边界情况
- [ ] 部署前进行审计
8. 进阶学习路线
初级 → 中级 → 高级
│ │ │
│ │ └── 形式化验证、MEV、跨链
│ │
│ └── DeFi 协议、NFT、DAO
│
└── Solidity 基础、ERC-20、测试
推荐资源:
- 📚 Solidity 官方文档
- 🎮 CryptoZombies — 游戏化学习
- 🛠️ OpenZeppelin — 安全合约库
- 💬 Ethereum Stack Exchange — 问答社区
总结
你已经学会了:
- ✅ 搭建 Hardhat 开发环境
- ✅ 编写 Solidity 智能合约
- ✅ 编写和运行测试
- ✅ 部署到 Sepolia 测试网
- ✅ 用前端连接钱包和合约
下一步: 尝试构建一个完整的 DApp,比如 NFT 铸造、DeFi 借贷、或去中心化投票系统。
📌 免责声明: 本文仅供教育目的。智能合约涉及真金白银,请充分测试后再部署到主网。
觉得有帮助?关注 @richard202605 获取更多 Web3 开发教程。有问题?评论区见!
Top comments (0)