关键词:以太坊钱包、Ethers.js、SolidJS、Web3 入门、智能合约前端开发、去中心化应用、Sepolia 测试网、助记词、加密存储
为什么用 Ethers.js + SolidJS?
在 Web3 开发浪潮下,一个能演示 以太坊钱包 基本功能的演示项目最具学习价值。SolidJS 具备 React 相同的函数式体验,同时比 React 更快、更轻;而 Ethers.js 则是社区最受欢迎的链上交互库,二者结合能极致简化以太坊转账 Demo 原型。
前置知识与环境
- Node.js ≥ 18
- 了解
npm create vite
与 TypeScript - 一个 Sepolia 测试网 API 节点(Infura 或 Alchemy,教程里用占位符即可)
第一步:用 Vite 初始化 SolidJS 项目
npm create vite@latest eth-wallet -- --template solid-ts
cd eth-wallet
npm i ethers crypto-js
ethers
:链上交互、助记词生成crypto-js
:本地 AES 加密,避免裸存私钥
第二步:架构梳理
- 用户首次进入 → 创建钱包
- 引导备份 助记词 → 加密 私钥 →
localStorage
- 再次进入 → 输入密码 加载钱包
- 展示 地址、余额 并实现 发送 ETH
第三步:核心代码拆解
示例仅贴关键片段,可直接替换 src/App.tsx
,完整文件见文末仓库地址。
3.1 状态定义
const [step, setStep] = createSignal(1); // 1创建 2备份 3主界面
const [wallet, setWallet] = createSignal<Wallet | null>(null);
const [balance, setBalance] = createSignal('0');
3.2 创建钱包
const createWallet = async () => {
const mnemonic = Wallet.createRandom().mnemonic.phrase;
const hdWallet = HDNodeWallet.fromMnemonic(Mnemonic.fromPhrase(mnemonic));
setPhrase(mnemonic);
const provider = new JsonRpcProvider(import.meta.env.VITE_RPC_URL);
hdWallet.connect(provider);
setWallet(hdWallet);
// AES 加密私钥
const cipher = CryptoJS.AES.encrypt(hdWallet.privateKey, password()).toString();
localStorage.setItem('encKey', cipher);
setStep(2);
};
3.3 加载已有钱包
const loadWallet = async () => {
const encKey = localStorage.getItem('encKey');
const bytes = CryptoJS.AES.decrypt(encKey!, password());
const privKey = bytes.toString(CryptoJS.enc.Utf8);
const provider = new JsonRpcProvider(import.meta.env.VITE_RPC_URL);
const restoredWallet = new Wallet(privKey, provider);
setWallet(restoredWallet);
const balRaw = await provider.getBalance(restoredWallet.address);
setBalance(formatEther(balRaw));
setStep(3);
};
3.4 UI 片段(SolidJS)
return (
<>
<Show when={step() === 1} keyed>
<h2>输入密码 {key ? '解锁钱包' : '创建钱包'}</h2>
<input type="password" onChange={e => setPassword(e.target.value)} />
<button onClick={() => key ? loadWallet() : createWallet()}>
{key ? '解锁' : '生成钱包'}
</button>
</Show>
<Show when={step() === 2} keyed>
<h3>📋 请抄写并离线保存 12 个助记词</h3>
<pre>{phrase()}</pre>
<button onClick={() => setStep(3)}>我已安全备份</button>
</Show>
<Show when={step() === 3} keyed>
<div>
<p>地址:{wallet()?.address}</p>
<p>余额:{balance()} ETH</p>
<input placeholder="收款地址" onChange={e => setRecipient(e.target.value)} />
<input placeholder="数量 (ETH)" type="number" onChange={e => setAmount(e.target.value)} />
<button onClick={sendEth}>转账</button>
{txHash() && (
<a href={`https://sepolia.etherscan.io/tx/${txHash()}`} target="_blank">
查看 Tx
</a>
)}
</div>
</Show>
</>
);
👉 在 5 分钟内从零构建可交互的以太坊钱包原型
第四步:发送 ETH 完整实现
const sendEth = async () => {
try {
const tx = await wallet()!.sendTransaction({
to: recipient(),
value: parseEther(amount())
});
setTxHash(tx.hash);
// 刷新余额
const balRaw = await wallet()!.provider.getBalance(wallet()!.address);
setBalance(formatEther(balRaw));
} catch (e) {
alert(`转账失败: ${e}`);
}
};
第五步:测试体验指南
- 准备测试币
生成钱包后复制地址,到 Sepolia 水龙头领取 0.1 ETH 足矣。 - 转账演示
将 0.05 ETH 转到另一个测试网地址,提交后 10 秒即可在 Sepolia Etherscan 看到交易状态。 - 热重载
npm run dev
开启本地热更新,刷新页面可模拟“解锁”场景。
第六步:进阶路线图
- 封装成 Chrome Extension(File System Access API 替代
localStorage
)。 - 支持 自定义 RPC 与 多链一键切换(Polygon、BNB Chain)。
- 引入 EIP-1559 Gas 手动设置 模块。
👉 查看完整源码与技术栈清单,立即获取 Tutorial 仓库
FAQ:新手常见疑惑
Q1:助记词能丢吗?
A:请 同时 离线抄写两份,一份放家里一份放公司保险箱。任何线上笔记、邮箱都可能被扫描,助记词一旦泄漏资产即归零。
Q2:为何不多用硬件钱包签名?
A:这里只做教学演示版。在生产级 DApp 中,推荐使用 WalletConnect + 硬件钱包签名,私钥永远不进浏览器。
Q3:为何用 Sepolia 而非 Görli?
A:Sepolia 测试网有 充足水龙头、出块稳定且合并成功后能耗更低,2025 年官方也长期维护。
Q4:SolidJS 和 React 差距大吗?
A:语法相似度 90%,只是将 useState
替换为 createSignal
,且响应式系统提前编译,性能更好,包体积更小。
Q5:crypto-js
AES 安全吗?
A:基本抗暴力,但 防不了浏览器插件读取内存。生产场景应换用 WebCrypto API 或 Argon2 等更现代方案。
Q6:如何批量监听多笔交易状态?
A:可订阅 provider.on('block')
每区块轮询,补充 setInterval
+ Promise.all
以免接口限速。
若想实时推送,改用 Websocket 提供者(WebSocketProvider)订阅 pending
或 receipt
。
至此,我们的极简以太坊钱包即完成。你可以把这段代码克隆到 GitHub,再扩展成公司 PoC 演示或 Hackathon 参赛作品。继续深挖 Web3 前端开发,不仅能感受区块链的新奇魅力,更能先人一步拥抱下一代互联网基础设施!