如何获取Etherscan展示的Uniswap交易对及交易数据?
用web3.js获取Uniswap交易的交易对、交易量及价格信息
针对你提到的这笔Uniswap V2交易,以下是用web3.js获取目标数据的具体方案:
核心思路
这笔交易是Uniswap V2 Pair合约上的Swap操作,需要通过Pair合约的只读方法和Swap事件日志提取数据,同时结合ERC20代币合约获取符号和小数位数完成单位转换。
步骤实现及代码示例
1. 初始化web3及合约ABI
引入web3并连接以太坊主网,定义所需的合约ABI片段(仅保留用到的方法和事件,减少冗余):
const Web3 = require('web3'); // 替换为你的Infura/Alchemy节点密钥 const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_PROJECT_KEY'); // Uniswap V2 Pair合约核心ABI片段 const pairAbi = [ { "constant": true, "inputs": [], "name": "token0", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "token1", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount0In", "type": "uint256" }, { "indexed": false, "name": "amount1In", "type": "uint256" }, { "indexed": false, "name": "amount0Out", "type": "uint256" }, { "indexed": false, "name": "amount1Out", "type": "uint256" }, { "indexed": true, "name": "to", "type": "address" } ], "name": "Swap", "type": "event" } ]; // ERC20代币核心ABI片段(获取符号和小数位数) const erc20Abi = [ { "constant": true, "inputs": [], "name": "symbol", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{ "name": "", "type": "uint8" }], "payable": false, "stateMutability": "view", "type": "function" } ];
2. 编写数据提取函数
通过交易哈希获取交易详情、Pair合约信息、Swap事件日志,最终计算出所需数据:
async function extractSwapData(txHash) { // 1. 获取交易的目标Pair合约地址 const tx = await web3.eth.getTransaction(txHash); const pairAddr = tx.to; // 2. 获取交易对的两个代币信息 const pairContract = new web3.eth.Contract(pairAbi, pairAddr); const [token0Addr, token1Addr] = await Promise.all([ pairContract.methods.token0().call(), pairContract.methods.token1().call() ]); const token0Contract = new web3.eth.Contract(erc20Abi, token0Addr); const token1Contract = new web3.eth.Contract(erc20Abi, token1Addr); const [token0Symbol, token1Symbol, token0Decimals, token1Decimals] = await Promise.all([ token0Contract.methods.symbol().call(), token1Contract.methods.symbol().call(), token0Contract.methods.decimals().call(), token1Contract.methods.decimals().call() ]); // 3. 解析Swap事件日志,获取交易量 const receipt = await web3.eth.getTransactionReceipt(txHash); const swapEvent = pairContract.decodeEventLog('Swap', receipt.logs[0].data, receipt.logs[0].topics); let token0Amount, token1Amount; // 判断交易方向:转入代币的amount>0,转出的amountOut>0 if (swapEvent.amount0In > 0) { token0Amount = swapEvent.amount0In / (10 ** token0Decimals); token1Amount = swapEvent.amount1Out / (10 ** token1Decimals); } else { token1Amount = swapEvent.amount1In / (10 ** token1Decimals); token0Amount = swapEvent.amount0Out / (10 ** token0Decimals); } // 4. 计算交易价格 const pricePerToken0 = (token1Amount / token0Amount).toFixed(6); // 返回整理后的结果 return { 交易对: `${token0Symbol}/${token1Symbol}`, [token0Symbol]: `${token0Amount.toFixed(8)}`, [token1Symbol]: `${token1Amount.toFixed(4)}`, 交易价格: `${pricePerToken0} ${token1Symbol} / ${token0Symbol}` }; } // 调用函数获取目标交易数据 extractSwapData('0x6ce8bbf5eca28a2a327b5f2b9f93ad5393c12bafe89f2cc379dd37ca9d1627b9') .then(result => console.log(result)) .catch(err => console.error('获取数据失败:', err));
关键说明
- 交易对顺序:Uniswap V2的
token0按地址字典序排序,若习惯将WETH作为报价代币,可在结果中判断并调整顺序。 - 小数位数处理:不同代币小数位数不同(如WBTC为8位,WETH为18位),必须除以
10^decimals才能得到人类可读数值。 - 事件日志解析:交易收据的
logs数组第一个日志即为Swap事件,直接解码即可获取原始交易量。
内容的提问来源于stack exchange,提问作者bbnn
相关产品推荐
相关产品推荐

