本文介绍如何使用 TypeScript 和 ethers.js 库在以太坊测试网络上执行 ETH 转账操作,涵盖地址生成、交易构建和区块链确认等关键环节。
准备工作
开始编码前,请确保满足以下条件:
- 已创建两个测试网络账户(本文使用 Sepolia 测试网)
- 其中一个钱包需持有测试 ETH
- 具备基础的 TypeScript 开发环境
本文演示用例中使用的账户信息:
钱包A(发送方)
- 地址:0x47FD9A30F48a656D9062aDE956c65f0ec8e2186c
- 余额:3.3455 ETH (Sepolia)
钱包B(接收方)
- 地址:0xc20e03E025C3F40772f9bDc0F9BeD896fB5E3dCA
- 余额:0.27525 ETH (Sepolia)
环境配置与依赖安装
首先创建 TypeScript 项目并安装必要依赖:
npm init -y
npm install ethers typescript ts-node创建 tsconfig.json 文件配置 TypeScript 编译器:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"esModuleInterop": true,
"strict": true
}
}生成以太坊地址
创建 generateAddress.ts 文件实现地址生成功能:
import { ethers } from 'ethers';
function generateEthereumAddress() {
const wallet = ethers.Wallet.createRandom();
return {
address: wallet.address,
privateKey: wallet.privateKey
};
}
const newAddress = generateEthereumAddress();
console.log(`地址(公钥): ${newAddress.address}`);
console.log(`私钥: ${newAddress.privateKey}`);运行生成脚本:
npx ts-node generateAddress.ts输出示例:
地址(公钥): 0x0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
私钥: 0x~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~实现 ETH 转账功能
创建 transfer.ts 文件实现转账逻辑:
import { ethers } from "ethers";
// 配置发送方私钥和接收方地址
const senderPrivateKey = '发送方钱包私钥'; // 替换为钱包A的私钥
const recipientAddress = '接收方钱包地址'; // 替换为钱包B的地址
// 连接 Sepolia 测试网络
const sepoliaProvider = new ethers.JsonRpcProvider('https://rpc.sepolia.org');
async function sendEth() {
// 初始化钱包实例
const wallet = new ethers.Wallet(senderPrivateKey, sepoliaProvider);
// 构建交易对象
const tx = {
to: recipientAddress,
value: ethers.parseEther("0.05") // 转账金额:0.05 ETH
};
// 发送交易
const txResponse = await wallet.sendTransaction(tx);
console.log('交易哈希:', txResponse.hash);
// 等待交易确认
const receipt = await txResponse.wait();
console.log('交易详情:', receipt);
}
sendEth();运行转账脚本:
npx ts-node transfer.ts成功输出示例:
交易哈希: 0xcfd4dbbb05f0424a97bf1db963c1d42b65dbbd3c930881a64e2c0e7dbe297447
交易详情: TransactionReceipt {
provider: JsonRpcProvider {},
to: '0xc20e03E025C3F40772f9bDc0F9BeD896fB5E3dCA',
from: '0x47FD9A30F48a656D9062aDE956c65f0ec8e2186c',
contractAddress: null,
hash: '0xcfd4dbbb05f0424a97bf1db963c1d42b65dbbd3c930881a64e2c0e7dbe297447',
index: 71,
blockHash: '0x4962365fc9a4f9211e8bfa0ad13a8b6139de3b589ff4fbe53e77b5b09428970b',
blockNumber: 5000125,
gasUsed: 21000n,
status: 1
}区块链交易验证
交易状态确认
通过交易哈希可在区块链浏览器上查询交易详情:
- 发送方: 0x47FD9A30F48a656D9062aDE956c65f0ec8e2186c (钱包A)
- 接收方: 0xc20e03E025C3F40772f9bDc0F9BeD896fB5E3dCA (钱包B)
- 状态: Success(成功)
余额变化验证
钱包A余额变化:
- 原始余额: 3.3455 ETH
- 转账后余额: 3.295477614670068 ETH
钱包B余额变化:
- 原始余额: 0.27525 ETH
- 转账后余额: 0.32525 ETH
手续费分析
实际扣除金额(0.050022385329932 ETH)大于转账金额(0.05 ETH),差额部分为网络手续费。手续费包含以下组成部分:
- 基础费用: 网络基本操作成本
- 优先费: 激励验证者优先处理交易的附加费用
最佳实践与安全建议
私钥安全管理
- 环境变量存储: 使用
process.env管理敏感信息 - 硬件钱包集成: 生产环境建议使用硬件钱包解决方案
- 多重签名机制: 大额转账建议采用多签合约
交易优化策略
- Gas 价格预测: 动态调整 Gas 价格以降低成本
- 交易监控: 实现交易状态实时监控机制
- 错误处理: 添加完整的异常处理逻辑
// 增强版错误处理示例
async function sendEthWithRetry() {
try {
const txResponse = await wallet.sendTransaction(tx);
const receipt = await txResponse.wait();
if (receipt.status === 1) {
console.log('交易成功');
} else {
console.log('交易失败');
}
} catch (error) {
console.error('交易异常:', error);
}
}常见问题
如何获取测试网 ETH?
Sepolia 测试网可通过官方水龙头获取测试 ETH:
- 访问 Sepolia 官方水龙头网站
- 输入你的钱包地址
- 通常可获得 0.5-1 ETH 测试币
交易为什么需要等待确认?
区块链网络需要时间达成共识:
- 交易需要被矿工打包进区块
- 多个区块确认可防止链重组
- 一般等待 3-6 个区块确认较为安全
交易失败常见原因有哪些?
- Gas 费用不足: 设置合适的 Gas 限额和价格
- 余额不足: 账户余额需覆盖转账金额+手续费
- 网络拥堵: 高峰期交易处理速度较慢
如何估算合理的 Gas 费用?
- 使用 ethers.js 的
estimateGas方法 - 参考区块链浏览器提供的平均 Gas 价格
- 根据交易紧急程度调整优先费
主网与测试网开发有何区别?
- 资产价值: 主网使用真实 ETH,测试网使用无价值测试币
- 网络稳定性: 测试网可能偶尔重置或不稳定
- 开发成本: 测试网无需真实资金成本
如何监控交易状态?
- 通过交易哈希在区块链浏览器查询
- 使用 WebSocket 订阅交易事件
- 实现轮询机制检查交易确认数
通过本文介绍的完整流程,你已掌握使用 TypeScript 进行 ETH 转账的核心技能。在实际应用中,建议进一步完善错误处理、气体优化和状态监控等功能,以确保应用的稳定性和用户体验。