随着区块链技术的普及,以太坊作为智能合约平台备受关注。对于开发者和数据分析师而言,获取链上地址及其余额是常见需求。本文将介绍如何利用 Web3.js 库实现这一目标,并提供详细的操作步骤与代码示例。
准备工作
在开始编码前,需确保本地环境已安装 Web3.js 模块。推荐通过 Node.js 进行集成管理,若网络访问速度较慢,可选用国内镜像源加速安装:
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install web3核心实现逻辑
获取以太坊地址与余额需遵循以下步骤:
- 获取当前区块高度:从创世区块开始遍历所有区块。
- 提取区块交易信息:解析每个区块中的交易哈希列表。
- 解析交易详情:从每笔交易中获取发送方(from)和接收方(to)地址。
- 区分地址类型:验证地址是否为合约地址。
- 查询余额:对符合条件的地查询其 ETH 余额。
代码实现详解
以下代码演示了如何通过 Web3.js 实现全流程操作:
var Web3 = require('web3');
console.log(Web3.version);
// 初始化 Web3 实例(主网节点)
var web3 = new Web3('https://mainnet.infura.io/');
// 获取最新区块编号
function getBlockNumber() {
web3.eth.getBlockNumber().then(function(result) {
console.log("blockNumber:" + result);
throughBlock(result);
});
}
// 遍历所有区块
function throughBlock(blockNumber) {
if (!blockNumber) { console.log('blockNumber is 0'); return false; };
for (var i = 0; i < blockNumber; i++) {
getBlock(i);
};
}
// 获取单个区块信息并提取交易
function getBlock(blockNumber) {
web3.eth.getBlock(blockNumber).then(function(result) {
transactions = result.transactions;
for (var i = 0; i < transactions.length; i++) {
getTransactions(transactions[i]);
}
});
}
// 解析交易对象获取地址
function getTransactions(txh) {
web3.eth.getTransaction(txh).then(function(result) {
from = result.from;
to = result.to;
getCode(from);
getCode(to);
});
}
// 检查地址是否为合约(非合约地址才查询余额)
function getCode(address) {
if (!address) { return false; };
web3.eth.getCode(address).then(function(result) {
if (result == '0x') {
getBalance(address);
};
});
}
// 查询地址余额并输出
function getBalance(address) {
web3.eth.getBalance(address).then(function(result) {
if (!addressList.includes(address)) {
addressList.push(address);
console.log(address + "\t" + result);
};
});
}
// 启动流程
getBlockNumber();运行与结果
将上述代码保存为 ethAddress.js 文件,通过以下命令执行:
node ethAddress.js程序将逐块扫描以太坊网络,输出所有非合约地址及其余额。👉 查看实时链上数据工具 可进一步辅助数据分析。
应用场景扩展
此方法不仅适用于余额统计,还可扩展至以下场景:
- 交易流水分析:追踪特定地址的所有交易记录。
- 资金流动监控:实时监控大额 ETH 转移动态。
- 智能合约交互:结合合约 ABI 实现更复杂的链上操作。
通过 Web3.js 的强大功能,开发者能构建与以太坊浏览器类似的服务,实现自定义区块链数据分析平台。
常见问题
1. Web3.js 支持哪些网络?
Web3.js 兼容以太坊主网、测试网(如 Rinkeby、Goerli)及私有链。只需切换节点提供商 URL 即可访问不同网络。
2. 如何区分合约地址与普通地址?
通过 web3.eth.getCode() 方法查询,若返回值为 0x 则为普通地址,否则为合约地址。
3. 为何要遍历所有区块?
以太坊网络中的交易分布在各个区块中,遍历区块可确保无遗漏地获取所有地址信息。
4. 查询速度受哪些因素影响?
节点响应速度、网络延迟及区块数量均会影响查询效率。建议使用高性能节点或增量同步策略优化。
5. 能否获取代币余额?
本文示例仅涉及 ETH 余额。如需查询代币余额,需调用代币合约的 balanceOf() 方法,并结合 ABI 解析结果。
6. 如何处理历史区块数据?
可通过设置起始区块号范围限制扫描范围,避免全量遍历带来的性能压力。