🧭 第 1 章:什么是区块链?为什么前端要学 Web3?
🌍 1.1 Web2 与 Web3 的核心区别
想象你在使用淘宝:
- 你输入账号密码;
 - 请求发送到"阿里巴巴的服务器";
 - 数据存储在"阿里的数据库";
 - 阿里说你余额是 100 元,那你就只能信它。
 
这是 Web2 模式:一切依赖中心服务器。
🔶 Web2 架构图
            
            
              css
              
              
            
          
          graph LR
A[前端浏览器] --> B[网站服务器]
B --> C[数据库]
        所有数据、逻辑、权限都由中间的"B 服务器"控制。
这意味着:
- 服务器关机,你的数据就"消失";
 - 平台可以随意封号;
 - 你不是"真正的拥有者"。
 
⚡ Web3 来了:让用户自己掌握数据
Web3 的目标是:
"让用户重新拥有自己的数据与资产"
这意味着:
- 数据存在区块链(任何人可验证);
 - 登录不再用密码,而是钱包签名;
 - 后端不再是服务器,而是「智能合约」。
 
🔷 Web3 架构图
            
            
              css
              
              
            
          
          graph LR
A[前端 DApp 应用] --> B[钱包 Provider]
A --> C[智能合约]
C --> D[区块链节点网络]
        🧠 用前端类比理解:
| Web2 | Web3 | 
|---|---|
| axios 调 REST API | ethers 调 JSON-RPC | 
| session 登录态 | 钱包签名登录 | 
| 服务器逻辑 | 智能合约逻辑 | 
| MySQL 数据 | 区块链存储 | 
| 用户依赖平台 | 用户拥有数据 | 
💬 小总结:
- Web3 不取代前端,而是让前端变得更强大;
 - 你不需要成为区块链专家,只要学会与钱包和合约交互;
 - Web3 世界的"后端"叫做 智能合约。
 
🧱 第 2 章:理解区块链的底层逻辑
🔍 2.1 什么是区块链?
通俗解释:
区块链是一条「大家共同维护的账本链」,
每一个"区块"都记录一组交易,
每个区块连接着前一个区块,就像链条一样。
🧩 区块链的结构图
            
            
              css
              
              
            
          
          graph LR
A[区块 #1] --> B[区块 #2] --> C[区块 #3]
        每个区块包含:
- 前一个区块的哈希值(防篡改)
 - 时间戳
 - 交易列表
 - 区块哈希(唯一 ID)
 
🔐 区块链的三大特性
- 去中心化(Decentralization)
没有单一服务器,全球数千节点同时存储账本。 - 不可篡改(Immutability)
一旦上链,就无法修改。 - 透明可验证(Transparency)
任何人都能通过区块浏览器查看交易记录。 
🧠 2.2 区块链是怎样"写入数据"的?
当你发起一笔交易(例如转账):
- 交易先被广播到整个网络;
 - "矿工"或"验证者"验证这笔交易是否合法;
 - 交易被打包进一个新的区块;
 - 区块被添加到链上;
 - 你看到交易"已确认"。
 
🔄 交易生命周期图
            
            
              rust
              
              
            
          
          sequenceDiagram
前端 ->> 钱包: 用户点击"转账"
钱包 ->> 区块链节点: 发送交易
节点 ->> 区块池: 广播交易
矿工 ->> 区块: 打包交易
区块 ->> 区块链: 添加新区块
前端 ->> 用户: 显示"交易成功"
        🪙 2.3 什么是智能合约?
智能合约是「运行在区块链上的自动执行程序」。
它像后端接口,但代码是公开的,部署后任何人都能调用。
语言叫 Solidity,运行在以太坊虚拟机(EVM)上。
举例,一个简单的"银行合约":
            
            
              ini
              
              
            
          
          pragma solidity ^0.8.0;
contract Bank {
    mapping(address => uint256) balances;
    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }
    function withdraw(uint amount) public {
        require(balances[msg.sender] >= amount, "余额不足");
        payable(msg.sender).transfer(amount);
        balances[msg.sender] -= amount;
    }
}
        🧩 合约调用图
            
            
              css
              
              
            
          
          graph TD
A[用户点击存款按钮] --> B[前端调用 ethers.js]
B --> C[MetaMask 弹出签名确认]
C --> D[交易上链]
D --> E[合约函数 deposit() 执行]
E --> F[链上更新余额映射 balances]
        ⚙️ 第 3 章:前端准备工作与钱包连接
💻 3.1 环境准备
| 工具 | 用途 | 下载 | 
|---|---|---|
| Node.js | 运行 JS | nodejs.org | 
| VS Code | 编辑器 | code.visualstudio.com | 
| MetaMask | 钱包插件 | metamask.io | 
安装完成后:
node -v
npm -v
        🦊 3.2 安装 MetaMask 并获取测试币
- 打开浏览器安装 MetaMask。
 - 创建钱包账户。
 - 切换到 
Sepolia测试网络。 - 前往 sepoliafaucet.com/ 获取测试 ETH。
 
⚠️ 这些测试币没有实际价值,只供开发调试使用。
🔌 3.3 前端如何检测钱包
            
            
              javascript
              
              
            
          
          if (typeof window.ethereum !== 'undefined') {
  console.log("✅ 检测到 MetaMask");
} else {
  console.log("❌ 请安装 MetaMask");
}
        如果浏览器中安装了 MetaMask,它会自动注入 window.ethereum。
🔗 3.4 用户授权并连接钱包
            
            
              javascript
              
              
            
          
          async function connectWallet() {
  const [account] = await window.ethereum.request({
    method: 'eth_requestAccounts'
  });
  console.log("连接的钱包地址:", account);
}
        执行过程:
- 用户点击"连接钱包";
 - MetaMask 弹出授权窗口;
 - 用户确认授权;
 - 前端拿到账户地址。
 
🧩 流程图
            
            
              rust
              
              
            
          
          sequenceDiagram
用户 ->> 前端: 点击"连接钱包"
前端 ->> MetaMask: 请求 eth_requestAccounts
MetaMask ->> 用户: 弹出授权确认
用户 ->> MetaMask: 同意授权
MetaMask ->> 前端: 返回账户地址
        💰 3.5 读取 ETH 余额
            
            
              javascript
              
              
            
          
          import { ethers } from 'ethers';
async function getBalance() {
  const provider = new ethers.BrowserProvider(window.ethereum);
  const [account] = await provider.send("eth_requestAccounts", []);
  const balance = await provider.getBalance(account);
  console.log("余额:", ethers.formatEther(balance), "ETH");
}
        🧠 3.6 前端完整演示(React 示例)
            
            
              javascript
              
              
            
          
          import { useState } from 'react';
import { ethers } from 'ethers';
export default function WalletConnector() {
  const [account, setAccount] = useState(null);
  const [balance, setBalance] = useState(null);
  async function connect() {
    const provider = new ethers.BrowserProvider(window.ethereum);
    const [addr] = await provider.send("eth_requestAccounts", []);
    setAccount(addr);
    const bal = await provider.getBalance(addr);
    setBalance(ethers.formatEther(bal));
  }
  return (
    <div style={{ padding: 30 }}>
      <h2>🦊 连接你的钱包</h2>
      {account ? (
        <>
          <p>钱包地址:{account}</p>
          <p>余额:{balance} ETH</p>
        </>
      ) : (
        <button onClick={connect}>连接钱包</button>
      )}
    </div>
  );
}
        🧩 3.7 钱包事件监听
            
            
              javascript
              
              
            
          
          window.ethereum.on('accountsChanged', (accounts) => {
  console.log("账户切换:", accounts[0]);
});
window.ethereum.on('chainChanged', (chainId) => {
  console.log("网络切换:", chainId);
});
        ✅ 小结
- Web3 的基本原理;
 - 区块链的结构和特性;
 - 前端如何检测并连接钱包;
 - 获取账户与余额;
 - 响应用户切换账户/网络事件。