2
月
在社区成长 2 月
LEVEL 1
1 XP
一、背景:Web3 新手真正需要掌握什么
很多新手第一次接触 Web3,会把注意力集中在币价、空投或某个钱包插件上,但从技术角度看,更重要的是理解一条完整的交互链路:用户保管私钥,钱包根据交易内容生成签名,RPC 节点把交易广播到区块链网络,验证者将交易打包进区块,最后由区块浏览器或程序查询执行结果。
本文以以太坊兼容链为例,带你在 Sepolia 测试网完成钱包准备、RPC 验证、余额查询、测试交易和简单合约部署。全部操作仅用于个人测试钱包、本地环境和公开测试网,不涉及真实目标或未授权安全测试。
二、核心概念与工作原理
1. 私钥与地址
私钥用于签名,是钱包资产控制权的根本。地址通常由公钥派生,可公开用于收款。知道地址并不能推出私钥,但拿到私钥、助记词或可解密的钱包文件,通常就意味着获得了账户控制权。
助记词不是普通登录密码,也不存在传统网站那种“忘记密码后找回”的机制。任何要求输入完整助记词的网页、客服或所谓验证工具,都应视为高风险。
2. 交易
一次典型交易至少包含以下信息:
- from:发起地址,由签名恢复得出;
- to:接收地址或合约地址;
- value:转移的原生代币数量;
- data:合约调用参数,普通转账通常为空;
- nonce:该账户的交易序号,用于防止重复执行;
- gasLimit:允许消耗的最大 Gas;
- maxFeePerGas 等费用参数:愿意支付的单位 Gas 上限;
- chainId:目标链标识,用于避免交易被错误地用于其他网络。
钱包签名的不是一句简单的“同意”,而是一组可执行数据。因此,确认交易时必须核对网络、目标地址、金额和调用内容。
3. RPC 节点
钱包通常不会自己保存整条区块链,而是通过 JSON-RPC 与节点通信,例如查询余额、估算 Gas、读取合约状态和广播已签名交易。RPC 可以看到你的 IP、查询频率和关注的地址,也可能返回错误或滞后的数据,但正常情况下无法仅凭 RPC 请求直接取得你的私钥。
4. 智能合约
智能合约是部署在链上的程序。读取状态一般不需要发送交易,也不会消耗用户的链上 Gas;修改状态则需要签名并发送交易。合约一旦部署,其代码和状态变化通常是公开可查的,写入链上的内容不应当被当作秘密数据。
三、前置条件
建议准备以下环境:
- 一台个人电脑,安装 Node.js 20 或更新的长期支持版本;
- 一个专门用于测试的独立钱包;
- Sepolia 测试网 RPC 地址;
- 少量 Sepolia 测试 ETH;
- 浏览器钱包或支持 WalletConnect 的钱包;
- 可选:Remix 在线 Solidity IDE。
务必新建测试钱包,不要导入存有真实资产的助记词。测试网代币通常没有实际价值,但测试钱包仍可能积累授权记录、签名习惯和隐私关联,因此也不应该随意泄露私钥。
四、分步骤实践
步骤 1:创建隔离的实验目录
在终端执行:
mkdir web3-sepolia-lab
cd web3-sepolia-lab
npm init -y
npm install ethers dotenv
创建 .gitignore 文件,内容如下:
.env
node_modules/
这样可以降低误把私钥或 RPC 密钥提交到 Git 仓库的风险。需要注意,.gitignore 只能防止正常的新增提交;如果秘密已经提交过,删除文件并不能抹掉历史记录,应立即更换私钥或服务端密钥。
步骤 2:配置测试网参数
创建 .env 文件:
SEPOLIA_RPC_URL=你的_Sepolia_RPC_地址
TEST_PRIVATE_KEY=你的独立测试钱包私钥
这里的私钥只能来自专门创建的测试钱包。不要使用主钱包,不要把 .env 发到群聊、网盘或截图中。更稳妥的做法是使用系统密钥库、硬件钱包或临时注入环境变量;本文使用 .env 只是为了降低入门门槛。
Sepolia 的 chainId 为 11155111。RPC 服务应从钱包、客户端或服务商的官方文档入口获取,不要直接采用群聊中来历不明的链接。
步骤 3:验证 RPC 连接和网络身份
创建 check-rpc.mjs:
import 'dotenv/config';
import { JsonRpcProvider } from 'ethers';
const provider = new JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const network = await provider.getNetwork();
const blockNumber = await provider.getBlockNumber();
console.log('chainId:', network.chainId.toString());
console.log('latest block:', blockNumber);
if (network.chainId !== 11155111n) {
throw new Error('当前 RPC 不是 Sepolia,请停止后续操作');
}
执行:
node check-rpc.mjs
这一步非常重要。链名只是界面文字,真正应该校验的是 chainId。若输出的 chainId 不是 11155111,不要继续请求测试币或发送交易。
步骤 4:查询测试钱包地址与余额
创建 balance.mjs:
import 'dotenv/config';
import { JsonRpcProvider, Wallet, formatEther } from 'ethers';
const provider = new JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const wallet = new Wallet(process.env.TEST_PRIVATE_KEY, provider);
const balance = await provider.getBalance(wallet.address);
console.log('address:', wallet.address);
console.log('balance:', formatEther(balance), 'ETH');
执行:
node balance.mjs
确认地址后,可通过可信的官方测试网水龙头申请少量 Sepolia 测试 ETH。水龙头入口和规则可能调整,应从以太坊官方开发者文档、可信钱包或基础设施服务商的正式页面进入。任何要求你先转入主网资产、提交助记词或安装陌生软件的“水龙头”都不可信。
步骤 5:发送一笔零金额自转交易
为了观察交易生命周期,可以向自己的地址发送 0 ETH。该操作仍会消耗测试网 Gas,但不会把测试币转给其他人。
创建 send-self.mjs:
import 'dotenv/config';
import { JsonRpcProvider, Wallet } from 'ethers';
const provider = new JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const network = await provider.getNetwork();
if (network.chainId !== 11155111n) {
throw new Error('拒绝发送:网络不是 Sepolia');
}
const wallet = new Wallet(process.env.TEST_PRIVATE_KEY, provider);
const fee = await provider.getFeeData();
console.log('sender:', wallet.address);
console.log('nonce:', await provider.getTransactionCount(wallet.address, 'pending'));
console.log('maxFeePerGas:', fee.maxFeePerGas?.toString());
const tx = await wallet.sendTransaction({
to: wallet.address,
value: 0n
});
console.log('transaction hash:', tx.hash);
console.log('等待确认中……');
const receipt = await tx.wait();
console.log('status:', receipt.status);
console.log('blockNumber:', receipt.blockNumber);
console.log('gasUsed:', receipt.gasUsed.toString());
执行:
node send-self.mjs
得到交易哈希后,可在可信的 Sepolia 区块浏览器中查询。重点观察交易状态、区块高度、发送方、接收方、nonce、Gas 使用量和实际手续费。如果 status 为 1,通常表示执行成功;若为 0,则说明交易已上链但执行回滚,Gas 一般不会退回。
步骤 6:在 Remix 中部署最小合约
先在 Remix 的本地虚拟机中练习,确认代码无误后再连接 Sepolia。新建 Counter.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Counter {
uint256 public number;
event NumberChanged(address indexed operator, uint256 newValue);
function setNumber(uint256 newValue) external {
number = newValue;
emit NumberChanged(msg.sender, newValue);
}
function increment() external {
number += 1;
emit NumberChanged(msg.sender, number);
}
}
实践顺序如下:
1. 使用与代码匹配的 Solidity 0.8.24 编译器进行编译;
2. 先选择 Remix VM 部署,不连接真实钱包;
3. 调用 number,观察只读调用不弹出交易确认;
4. 调用 increment,观察本地交易和事件日志;
5. 确认理解流程后,再选择浏览器钱包提供的环境;
6. 在钱包中再次检查网络必须为 Sepolia;
7. 部署前核对合约代码、预估费用和部署账户;
8. 部署完成后保存合约地址和交易哈希;
9. 调用 setNumber 或 increment,并在浏览器中查看 Input Data 和事件。
不要直接复制陌生人提供的合约代码后部署。构造函数、代理合约、外部调用、授权逻辑和自毁相关行为都可能改变实际风险。示例 Counter 只用于理解状态读取、状态修改和事件日志,不应当被视为生产级业务合约。
五、从安全角度理解主要攻击面
1. 助记词和私钥泄露
常见来源包括剪贴板同步、恶意输入法、云端备份、截图、远程控制软件、浏览器恶意扩展和代码仓库误提交。修复思路是钱包隔离、减少秘密复制、关闭不必要的云同步、使用硬件钱包,并让生产资产与开发测试账户彻底分离。
2. 盲签和钓鱼签名
并非只有转账会造成损失。某些消息签名可能用于登录、挂单、授权或委托,合约交易还可能授予代币额度。签名前应核对站点域名、链、合约地址、函数、参数、授权对象和额度。无法解释的签名请求应直接拒绝。
3. 无限授权
ERC-20 approve 常见的无限额度虽然方便,却会扩大后续风险。如果被授权合约或相关密钥出现问题,攻击者可能在额度范围内转走代币。更安全的做法是按需授权、使用后撤销、定期检查授权记录,并避免给未经验证的合约开放无限额度。
4. 恶意 RPC 与隐私泄露
RPC 能关联 IP、钱包地址和查询行为,也可能返回延迟数据。涉及较高价值操作时,可以使用多个可信来源交叉验证余额、nonce、链 ID 和交易状态。签名应在本地钱包或硬件设备中完成,不应把私钥提交给 RPC 服务。
5. 手机钱包特有风险
移动端应特别关注深度链接和 WalletConnect 会话。恶意应用可能伪造跳转页面,诱导用户在钱包中确认另一笔请求;具备无障碍、悬浮窗、录屏或通知读取权限的恶意软件,也可能窃取敏感界面信息。建议从官方应用商店或官网入口安装钱包,关闭不必要的高危权限,设置独立锁屏和钱包口令,并及时断开不再使用的 WalletConnect 会话。
6. 地址替换
复制地址后,应至少核对前后若干字符;高价值操作最好完整核对,或先进行小额验证。不要只依赖“地址开头和结尾看起来相似”,因为攻击者可能生成具有相似片段的地址。
六、常见问题
问题 1:测试网代币可以兑换成真钱吗?
通常不能。测试币用于支付测试网 Gas,没有官方兑换价值。宣称可以高价回收测试币并要求先支付手续费、授权代币或输入助记词的行为很可能是骗局。
问题 2:交易长时间 pending 怎么办?
先检查 RPC 是否同步、账户余额是否足够、费用设置是否合理,以及同一账户是否存在更低 nonce 的待处理交易。不要连续无脑重发,否则容易形成 nonce 队列。钱包的加速功能通常是用相同 nonce 和更高费用替换原交易。
问题 3:为什么合约调用失败仍然扣 Gas?
因为验证者已经执行了交易并消耗计算和存储资源。合约回滚会撤销状态变化,但通常不会退还已经消耗的全部 Gas。发送前可先进行 estimateGas 或静态模拟,但模拟成功也不能绝对保证上链时状态没有变化。
问题 4:钱包显示成功,区块浏览器却暂时查不到?
可能是钱包已广播但节点尚未收录,也可能是钱包和浏览器连接了不同网络。首先核对 chainId 和交易哈希,再更换可信 RPC 或等待区块确认。不要仅凭某个界面的提示判断最终状态。
问题 5:撤销代币授权后,过去的交易会消失吗?
不会。区块链历史记录仍然存在,撤销授权只是把当前可使用额度降低为零或新的数值,并不能删除已经发生的授权和转账记录。
七、总结
Web3 入门不应停留在“安装钱包并点击确认”。一套可靠的操作习惯应包括:使用独立测试钱包、验证 chainId、理解交易字段、保护私钥、先在本地或测试网实践、核对签名内容、控制代币授权,并通过交易回执和区块浏览器验证结果。
完成本文实验后,你应当能够解释钱包、RPC、交易、Gas、nonce 和智能合约之间的关系,并独立完成一次 Sepolia 测试网交互。后续可以继续学习 ABI 编码、事件过滤、交易模拟、合约权限控制和硬件钱包签名,但无论技术如何深入,都应坚持一个基本原则:私钥只用于本地签名,任何链上操作都先读懂、再确认。
很多新手第一次接触 Web3,会把注意力集中在币价、空投或某个钱包插件上,但从技术角度看,更重要的是理解一条完整的交互链路:用户保管私钥,钱包根据交易内容生成签名,RPC 节点把交易广播到区块链网络,验证者将交易打包进区块,最后由区块浏览器或程序查询执行结果。
本文以以太坊兼容链为例,带你在 Sepolia 测试网完成钱包准备、RPC 验证、余额查询、测试交易和简单合约部署。全部操作仅用于个人测试钱包、本地环境和公开测试网,不涉及真实目标或未授权安全测试。
二、核心概念与工作原理
1. 私钥与地址
私钥用于签名,是钱包资产控制权的根本。地址通常由公钥派生,可公开用于收款。知道地址并不能推出私钥,但拿到私钥、助记词或可解密的钱包文件,通常就意味着获得了账户控制权。
助记词不是普通登录密码,也不存在传统网站那种“忘记密码后找回”的机制。任何要求输入完整助记词的网页、客服或所谓验证工具,都应视为高风险。
2. 交易
一次典型交易至少包含以下信息:
- from:发起地址,由签名恢复得出;
- to:接收地址或合约地址;
- value:转移的原生代币数量;
- data:合约调用参数,普通转账通常为空;
- nonce:该账户的交易序号,用于防止重复执行;
- gasLimit:允许消耗的最大 Gas;
- maxFeePerGas 等费用参数:愿意支付的单位 Gas 上限;
- chainId:目标链标识,用于避免交易被错误地用于其他网络。
钱包签名的不是一句简单的“同意”,而是一组可执行数据。因此,确认交易时必须核对网络、目标地址、金额和调用内容。
3. RPC 节点
钱包通常不会自己保存整条区块链,而是通过 JSON-RPC 与节点通信,例如查询余额、估算 Gas、读取合约状态和广播已签名交易。RPC 可以看到你的 IP、查询频率和关注的地址,也可能返回错误或滞后的数据,但正常情况下无法仅凭 RPC 请求直接取得你的私钥。
4. 智能合约
智能合约是部署在链上的程序。读取状态一般不需要发送交易,也不会消耗用户的链上 Gas;修改状态则需要签名并发送交易。合约一旦部署,其代码和状态变化通常是公开可查的,写入链上的内容不应当被当作秘密数据。
三、前置条件
建议准备以下环境:
- 一台个人电脑,安装 Node.js 20 或更新的长期支持版本;
- 一个专门用于测试的独立钱包;
- Sepolia 测试网 RPC 地址;
- 少量 Sepolia 测试 ETH;
- 浏览器钱包或支持 WalletConnect 的钱包;
- 可选:Remix 在线 Solidity IDE。
务必新建测试钱包,不要导入存有真实资产的助记词。测试网代币通常没有实际价值,但测试钱包仍可能积累授权记录、签名习惯和隐私关联,因此也不应该随意泄露私钥。
四、分步骤实践
步骤 1:创建隔离的实验目录
在终端执行:
mkdir web3-sepolia-lab
cd web3-sepolia-lab
npm init -y
npm install ethers dotenv
创建 .gitignore 文件,内容如下:
.env
node_modules/
这样可以降低误把私钥或 RPC 密钥提交到 Git 仓库的风险。需要注意,.gitignore 只能防止正常的新增提交;如果秘密已经提交过,删除文件并不能抹掉历史记录,应立即更换私钥或服务端密钥。
步骤 2:配置测试网参数
创建 .env 文件:
SEPOLIA_RPC_URL=你的_Sepolia_RPC_地址
TEST_PRIVATE_KEY=你的独立测试钱包私钥
这里的私钥只能来自专门创建的测试钱包。不要使用主钱包,不要把 .env 发到群聊、网盘或截图中。更稳妥的做法是使用系统密钥库、硬件钱包或临时注入环境变量;本文使用 .env 只是为了降低入门门槛。
Sepolia 的 chainId 为 11155111。RPC 服务应从钱包、客户端或服务商的官方文档入口获取,不要直接采用群聊中来历不明的链接。
步骤 3:验证 RPC 连接和网络身份
创建 check-rpc.mjs:
import 'dotenv/config';
import { JsonRpcProvider } from 'ethers';
const provider = new JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const network = await provider.getNetwork();
const blockNumber = await provider.getBlockNumber();
console.log('chainId:', network.chainId.toString());
console.log('latest block:', blockNumber);
if (network.chainId !== 11155111n) {
throw new Error('当前 RPC 不是 Sepolia,请停止后续操作');
}
执行:
node check-rpc.mjs
这一步非常重要。链名只是界面文字,真正应该校验的是 chainId。若输出的 chainId 不是 11155111,不要继续请求测试币或发送交易。
步骤 4:查询测试钱包地址与余额
创建 balance.mjs:
import 'dotenv/config';
import { JsonRpcProvider, Wallet, formatEther } from 'ethers';
const provider = new JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const wallet = new Wallet(process.env.TEST_PRIVATE_KEY, provider);
const balance = await provider.getBalance(wallet.address);
console.log('address:', wallet.address);
console.log('balance:', formatEther(balance), 'ETH');
执行:
node balance.mjs
确认地址后,可通过可信的官方测试网水龙头申请少量 Sepolia 测试 ETH。水龙头入口和规则可能调整,应从以太坊官方开发者文档、可信钱包或基础设施服务商的正式页面进入。任何要求你先转入主网资产、提交助记词或安装陌生软件的“水龙头”都不可信。
步骤 5:发送一笔零金额自转交易
为了观察交易生命周期,可以向自己的地址发送 0 ETH。该操作仍会消耗测试网 Gas,但不会把测试币转给其他人。
创建 send-self.mjs:
import 'dotenv/config';
import { JsonRpcProvider, Wallet } from 'ethers';
const provider = new JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const network = await provider.getNetwork();
if (network.chainId !== 11155111n) {
throw new Error('拒绝发送:网络不是 Sepolia');
}
const wallet = new Wallet(process.env.TEST_PRIVATE_KEY, provider);
const fee = await provider.getFeeData();
console.log('sender:', wallet.address);
console.log('nonce:', await provider.getTransactionCount(wallet.address, 'pending'));
console.log('maxFeePerGas:', fee.maxFeePerGas?.toString());
const tx = await wallet.sendTransaction({
to: wallet.address,
value: 0n
});
console.log('transaction hash:', tx.hash);
console.log('等待确认中……');
const receipt = await tx.wait();
console.log('status:', receipt.status);
console.log('blockNumber:', receipt.blockNumber);
console.log('gasUsed:', receipt.gasUsed.toString());
执行:
node send-self.mjs
得到交易哈希后,可在可信的 Sepolia 区块浏览器中查询。重点观察交易状态、区块高度、发送方、接收方、nonce、Gas 使用量和实际手续费。如果 status 为 1,通常表示执行成功;若为 0,则说明交易已上链但执行回滚,Gas 一般不会退回。
步骤 6:在 Remix 中部署最小合约
先在 Remix 的本地虚拟机中练习,确认代码无误后再连接 Sepolia。新建 Counter.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Counter {
uint256 public number;
event NumberChanged(address indexed operator, uint256 newValue);
function setNumber(uint256 newValue) external {
number = newValue;
emit NumberChanged(msg.sender, newValue);
}
function increment() external {
number += 1;
emit NumberChanged(msg.sender, number);
}
}
实践顺序如下:
1. 使用与代码匹配的 Solidity 0.8.24 编译器进行编译;
2. 先选择 Remix VM 部署,不连接真实钱包;
3. 调用 number,观察只读调用不弹出交易确认;
4. 调用 increment,观察本地交易和事件日志;
5. 确认理解流程后,再选择浏览器钱包提供的环境;
6. 在钱包中再次检查网络必须为 Sepolia;
7. 部署前核对合约代码、预估费用和部署账户;
8. 部署完成后保存合约地址和交易哈希;
9. 调用 setNumber 或 increment,并在浏览器中查看 Input Data 和事件。
不要直接复制陌生人提供的合约代码后部署。构造函数、代理合约、外部调用、授权逻辑和自毁相关行为都可能改变实际风险。示例 Counter 只用于理解状态读取、状态修改和事件日志,不应当被视为生产级业务合约。
五、从安全角度理解主要攻击面
1. 助记词和私钥泄露
常见来源包括剪贴板同步、恶意输入法、云端备份、截图、远程控制软件、浏览器恶意扩展和代码仓库误提交。修复思路是钱包隔离、减少秘密复制、关闭不必要的云同步、使用硬件钱包,并让生产资产与开发测试账户彻底分离。
2. 盲签和钓鱼签名
并非只有转账会造成损失。某些消息签名可能用于登录、挂单、授权或委托,合约交易还可能授予代币额度。签名前应核对站点域名、链、合约地址、函数、参数、授权对象和额度。无法解释的签名请求应直接拒绝。
3. 无限授权
ERC-20 approve 常见的无限额度虽然方便,却会扩大后续风险。如果被授权合约或相关密钥出现问题,攻击者可能在额度范围内转走代币。更安全的做法是按需授权、使用后撤销、定期检查授权记录,并避免给未经验证的合约开放无限额度。
4. 恶意 RPC 与隐私泄露
RPC 能关联 IP、钱包地址和查询行为,也可能返回延迟数据。涉及较高价值操作时,可以使用多个可信来源交叉验证余额、nonce、链 ID 和交易状态。签名应在本地钱包或硬件设备中完成,不应把私钥提交给 RPC 服务。
5. 手机钱包特有风险
移动端应特别关注深度链接和 WalletConnect 会话。恶意应用可能伪造跳转页面,诱导用户在钱包中确认另一笔请求;具备无障碍、悬浮窗、录屏或通知读取权限的恶意软件,也可能窃取敏感界面信息。建议从官方应用商店或官网入口安装钱包,关闭不必要的高危权限,设置独立锁屏和钱包口令,并及时断开不再使用的 WalletConnect 会话。
6. 地址替换
复制地址后,应至少核对前后若干字符;高价值操作最好完整核对,或先进行小额验证。不要只依赖“地址开头和结尾看起来相似”,因为攻击者可能生成具有相似片段的地址。
六、常见问题
问题 1:测试网代币可以兑换成真钱吗?
通常不能。测试币用于支付测试网 Gas,没有官方兑换价值。宣称可以高价回收测试币并要求先支付手续费、授权代币或输入助记词的行为很可能是骗局。
问题 2:交易长时间 pending 怎么办?
先检查 RPC 是否同步、账户余额是否足够、费用设置是否合理,以及同一账户是否存在更低 nonce 的待处理交易。不要连续无脑重发,否则容易形成 nonce 队列。钱包的加速功能通常是用相同 nonce 和更高费用替换原交易。
问题 3:为什么合约调用失败仍然扣 Gas?
因为验证者已经执行了交易并消耗计算和存储资源。合约回滚会撤销状态变化,但通常不会退还已经消耗的全部 Gas。发送前可先进行 estimateGas 或静态模拟,但模拟成功也不能绝对保证上链时状态没有变化。
问题 4:钱包显示成功,区块浏览器却暂时查不到?
可能是钱包已广播但节点尚未收录,也可能是钱包和浏览器连接了不同网络。首先核对 chainId 和交易哈希,再更换可信 RPC 或等待区块确认。不要仅凭某个界面的提示判断最终状态。
问题 5:撤销代币授权后,过去的交易会消失吗?
不会。区块链历史记录仍然存在,撤销授权只是把当前可使用额度降低为零或新的数值,并不能删除已经发生的授权和转账记录。
七、总结
Web3 入门不应停留在“安装钱包并点击确认”。一套可靠的操作习惯应包括:使用独立测试钱包、验证 chainId、理解交易字段、保护私钥、先在本地或测试网实践、核对签名内容、控制代币授权,并通过交易回执和区块浏览器验证结果。
完成本文实验后,你应当能够解释钱包、RPC、交易、Gas、nonce 和智能合约之间的关系,并独立完成一次 Sepolia 测试网交互。后续可以继续学习 ABI 编码、事件过滤、交易模拟、合约权限控制和硬件钱包签名,但无论技术如何深入,都应坚持一个基本原则:私钥只用于本地签名,任何链上操作都先读懂、再确认。