:2026-02-17 4:57 点击:8
在区块链的世界里,以太坊作为最智能的合约平台之一,其代币(如ETH及各种ERC20代币)的转移是核心操作之一,对于开发者而言,掌握如何通过代码安全、有效地将钱包中的余额转出,是一项至关重要的技能,本文将详细介绍以太坊钱包余额转账的核心代码实现,涵盖基本原理、代码示例(以JavaScript和Solidity为例)以及关键注意事项。
以太坊上的转账本质上是一次交易(Transaction),发起转账时,发送方(From账户)需要向以太坊网络广播一笔包含以下关键信息的交易:
当矿工(或验证者)打包这笔交易时,会从中扣除相应的Gas费用(Gas Limit * Gas Price),然后将资产从发送方地址转移到接收方地址。
在编写代码之前,你需要准备以下工具和环境:
ethers.js 或 web3.js:用于与以太坊交互的JavaScript库,本文主要使用ethers.js,因其更现代且API友好。solc:Solidity编译器,如果需要编译Solidity合约。这是最常见的情况,即从一个外部拥有账户(EOA)通过代码发送ETH或ERC20代币。
const ethers = require("ethers");
// 1. 配置Provider(连接到以太坊网络)
const provider = new ethers.providers.JsonRpcProvider("https://goerli.infura.io/v3/YOUR_INFURA_PROJECT_ID"); // 替换为你的Infura ID或节点URL
// 2. 创建Wallet(从私钥创建,实际应用中应从安全的地方获取,如硬件钱包、环境变量等)
// 警告:不要将私钥直接写在代码中!这里仅作示例
const privateKey = "YOUR_PRIVATE_KEY"; // 替换为发送方的私钥
const wallet = new ethers.Wallet(privateKey, provider);
// 3. 接收方地址
const recipientAddress = "0xRecipientAddressHere..."; // 替换为接收方地址
// 4. 转账金额(以ETH为单位,转换为wei)
const amountToSend = ethers.utils.parseEther("0.01"); // 转账0.01 ETH
// 5. 构建并发送交易
async function sendEthTransaction() {
try {
// 获取当前nonce(防止交易重复)
const nonce = await wallet.getTransactionCount();
// 构建交易对象
const tx = {
to: recipientAddress,
value: amountToSend,
gasLimit: ethers.utils.hexlify(21000), // ETH转账通常21000 gas
nonce: nonce,
chainId: 5, // Goerli测试网的chainId,主网为1
};
// 发送交易(会返回交易哈希)
const txResponse = await wallet.sendTransaction(tx);
console.log("交易已发送,哈希:", txResponse.hash);
// 等待交易被打包
const txReceipt = await txResponse.wait();
console.log("交易已确认,区块号:", txReceipt.blockNumber);
console.log("余额已转出!");
} catch (error) {
console.error("转账失败:", error);
}
}
sendEthTransaction();
ERC20代币的转账不是直接调用transfer方法到接收方地址,而是调用代币合约的transfer方法,参数为接收方地址和转账金额。
const ethers = require("ethers");
// 1. 配置Provider和Wallet(同上)
const provider = new ethers.providers.JsonRpcProvider("https://goerli.infura.io/v3/YOUR_INFURA_PROJECT_ID");
const privateKey = "YOUR_PRIVATE_KEY";
const wallet = new ethers.Wallet(privateKey, provider);
// 2.
ERC20代币合约地址(以Goerli测试网的DAI为例)
const tokenAddress = "0x11fE4B6AE13d2a6055C8D9cF65c22B0E383A8687"; // 替换为你要转账的代币合约地址
// 3. 接收方地址
const recipientAddress = "0xRecipientAddressHere...";
// 4. 代币合约ABI(只需包含transfer方法)
const tokenAbi = [
"function transfer(address to, uint amount) returns (bool)",
"function balanceOf(address account) view returns (uint)",
"function decimals() view returns (uint8)"
];
// 5. 创建代币合约实例
const tokenContract = new ethers.Contract(tokenAddress, tokenAbi, wallet);
// 6. 转账金额(注意代币的decimals)
const amountToSend = ethers.utils.parseUnits("100", 18); // 假设代币有18位小数,转账100个代币
async function sendErc20Transaction() {
try {
// 获取当前nonce
const nonce = await wallet.getTransactionCount();
// 调用代币合约的transfer方法
const txResponse = await tokenContract.transfer(recipientAddress, amountToSend);
console.log("代币转账交易已发送,哈希:", txResponse.hash);
// 等待交易被打包
const txReceipt = await txResponse.wait();
console.log("代币转账交易已确认,区块号:", txReceipt.blockNumber);
console.log("代币余额已转出!");
} catch (error) {
console.error("代币转账失败:", error);
}
}
// 可选:先查询发送方代币余额
async function checkTokenBalance() {
const balance = await tokenContract.balanceOf(wallet.address);
console.log(`发送方 ${wallet.address} 的代币余额:`, ethers.utils.formatUnits(balance, 18));
}
checkTokenBalance().then(() => sendErc20Transaction());
如果你想在智能合约内部实现余额转出(合约管理员提取资金或用户提取收益),代码会略有不同。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract EtherWallet {
address public owner;
constructor() {
owner = msg.sender; // 部署者成为所有者
}
// 接收ETH
receive() external payable {}
// 提取ETH到指定地址
function withdrawEth(address payable _to, uint256 _amount) external {
require(msg.sender == owner, "Only owner can withdraw");
require(address(this).balance >= _amount, "Insufficient balance");
// 转账ETH
(bool success, ) = _to.call{value: _amount}("");
require(success, "ETH transfer failed");
}
// 查询合约ETH余额
function getBalance() external view returns (uint256) {
return address(this).balance;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract TokenWallet {
address public owner;
constructor() {
owner = msg.sender;
}
// 提取ERC20代币到指定地址
function withdrawErc20(address _tokenAddress, address _to, uint256 _amount) external {
require(msg.sender ==
本文由用户投稿上传,若侵权请提供版权资料并联系删除!