You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Uniswap V3相关JS代码的console.log输出保存到文件?

如何将Uniswap V3数据的console.log输出保存到文件(适配Python解析)

要把代码中打印的代币数据保存到文件并方便Python解析,最直接的方式是将输出整理为JSON结构化格式后写入文件,而非单纯捕获console.log的文本输出。以下是具体修改方案:

一、修改JavaScript代码,写入结构化JSON数据

你的代码已经导入了fs模块,只需调整getTokenAmounts函数,将需要保存的数据整理为对象后写入文件,同时保留原有控制台输出:

import { JSBI } from "@uniswap/sdk";
import { ethers } from 'ethers';
import * as fs from 'fs';

// ERC20 JSON ABI 文件
let ERC20Abi = fs.readFileSync('ERC20.json');
const ERC20 = JSON.parse(ERC20Abi);

// V3 池 ABI JSON 文件
let pool = fs.readFileSync('V3PairAbi.json');
const IUniswapV3PoolABI = JSON.parse(pool);

// V3 工厂 ABI JSON 文件
let facto = fs.readFileSync('V3factory.json');
const IUniswapV3FactoryABI = JSON.parse(facto);

let NFT = fs.readFileSync('UniV3NFT.json');
const IUniswapV3NFTmanagerABI = JSON.parse(NFT);

const provider = new ethers.providers.JsonRpcProvider(ALCHEMY)

// V3 标准地址(Celo 链不同)
const factory = FACTORY;
const NFTmanager = NFTMANAGER;

async function getData(tokenID){
    let FactoryContract = new ethers.Contract(factory, IUniswapV3FactoryABI, provider);

    let NFTContract =  new ethers.Contract(NFTmanager, IUniswapV3NFTmanagerABI, provider);
    let position = await NFTContract.positions(tokenID);
    
    let token0contract =  new ethers.Contract(position.token0, ERC20, provider);
    let token1contract =  new ethers.Contract(position.token1, ERC20, provider);
    let token0Decimal = await token0contract.decimals();
    let token1Decimal = await token1contract.decimals();
    
    let token0sym = await token0contract.symbol();
    let token1sym = await token1contract.symbol();
    
    let V3pool = await FactoryContract.getPool(position.token0, position.token1, position.fee);
    let poolContract = new ethers.Contract(V3pool, IUniswapV3PoolABI, provider);

    let slot0 = await poolContract.slot0();

    
    let pairName = token0sym +"/"+ token1sym;
    
    let dict = {"SqrtX96" : slot0.sqrtPriceX96.toString(), "Pair": pairName, "T0d": token0Decimal, "T1d": token1Decimal, "tickLow": position.tickLower.toString(), "tickHigh": position.tickUpper.toString(), "liquidity": position.liquidity.toString()}

    return dict
}


const Q96 = JSBI.exponentiate(JSBI.BigInt(2), JSBI.BigInt(96));
const MIN_TICK = -887272;
const MAX_TICK = 887272;

function getTickAtSqrtRatio(sqrtPriceX96){
    let tick = Math.floor(Math.log((sqrtPriceX96/Q96)**2)/Math.log(1.0001));
    return tick;
}

async function getTokenAmounts(liquidity,sqrtPriceX96,tickLow,tickHigh,token0Decimal,token1Decimal){
    let sqrtRatioA = Math.sqrt(1.0001**tickLow).toFixed(18);
    let sqrtRatioB = Math.sqrt(1.0001**tickHigh).toFixed(18);
    let currentTick = getTickAtSqrtRatio(sqrtPriceX96);
    let sqrtPrice = sqrtPriceX96 / Q96;
    let amount0wei = 0;
    let amount1wei = 0;
    if(currentTick <= tickLow){
        amount0wei = Math.floor(liquidity*((sqrtRatioB-sqrtRatioA)/(sqrtRatioA*sqrtRatioB)));
    }
    if(currentTick > tickHigh){
        amount1wei = Math.floor(liquidity*(sqrtRatioB-sqrtRatioA));
    }
    if(currentTick >= tickLow && currentTick < tickHigh){ 
        amount0wei = Math.floor(liquidity*((sqrtRatioB-sqrtPrice)/(sqrtPrice*sqrtRatioB)));
        amount1wei = Math.floor(liquidity*(sqrtPrice-sqrtRatioA));
    }
    
    let amount0Human = (amount0wei/(10**token0Decimal)).toFixed(token0Decimal);
    let amount1Human = (amount1wei/(10**token1Decimal)).toFixed(token1Decimal);

    // 整理需要保存的结构化数据
    const outputData = {
        amount0Wei: amount0wei.toString(),
        amount1Wei: amount1wei.toString(),
        amount0Human: amount0Human,
        amount1Human: amount1Human,
        liquidity: liquidity,
        sqrtPriceX96: sqrtPriceX96.toString(),
        tickLow: tickLow.toString(),
        tickHigh: tickHigh.toString(),
        token0Decimal: token0Decimal,
        token1Decimal: token1Decimal
    };

    // 保留原有控制台输出
    console.log("Amount Token0 wei: "+amount0wei);
    console.log("Amount Token1 wei: "+amount1wei);
    console.log("Amount Token0 : "+amount0Human);
    console.log("Amount Token1 : "+amount1Human);

    // 写入JSON文件(追加模式,避免覆盖已有数据)
    try {
        fs.appendFileSync('uniswap_v3_token_data.json', JSON.stringify(outputData) + '\n');
        console.log("数据已写入文件: uniswap_v3_token_data.json");
    } catch (err) {
        console.error("写入文件失败:", err);
    }

    return [amount0wei, amount1wei]
}

async function start(positionID){
    let data = await getData(positionID);
    let tokens = await getTokenAmounts(data.liquidity, data.SqrtX96, data.tickLow, data.tickHigh, data.T0d, data.T1d);
    
    // 可选:将仓位信息与代币数据整合后单独保存
    const fullPositionData = {
        ...data,
        amount0Wei: tokens[0].toString(),
        amount1Wei: tokens[1].toString()
    };
    try {
        fs.appendFileSync('uniswap_v3_full_position_data.json', JSON.stringify(fullPositionData) + '\n');
        console.log("完整仓位数据已写入文件: uniswap_v3_full_position_data.json");
    } catch (err) {
        console.error("写入完整仓位数据失败:", err);
    }
}

start(POOLID)
// 若自行获取数据,无需仓位信息也可适用于任何区间
getTokenAmounts(12558033400096537032, 20259533801624375790673555415)

修改说明:

  1. 将所有需要保存的字段整理为outputData对象,确保数据类型可被JSON序列化(BigInt或大数转为字符串)
  2. 使用fs.appendFileSync以追加模式写入文件,每次运行新增一条数据,避免覆盖历史记录
  3. 可选:在start函数中整合仓位信息与代币数据,生成更完整的输出文件

二、Python解析JSON文件示例

由于保存的是每行一个JSON对象的格式,Python可以逐行读取解析,无需一次性加载全部数据:

import json

# 解析代币数量数据文件
with open('uniswap_v3_token_data.json', 'r', encoding='utf-8') as f:
    for line in f:
        try:
            data = json.loads(line.strip())
            print(f"Token0 可读数量: {data['amount0Human']}")
            print(f"Token1 Wei数量: {data['amount1Wei']}")
            # 按需处理其他字段
        except json.JSONDecodeError as e:
            print(f"解析行失败: {e}")

# 解析完整仓位数据文件
with open('uniswap_v3_full_position_data.json', 'r', encoding='utf-8') as f:
    for line in f:
        try:
            data = json.loads(line.strip())
            print(f"交易对: {data['Pair']}")
            print(f"当前价格SqrtX96: {data['SqrtX96']}")
            # 按需处理其他字段
        except json.JSONDecodeError as e:
            print(f"解析行失败: {e}")

三、备选方案:命令行重定向输出

如果不需要结构化数据,仅需捕获所有console.log输出,可在运行代码时使用命令行重定向:

node your_script_name.js > uniswap_output.txt 2>&1
  • > 将标准输出写入文件
  • 2>&1 将错误输出也重定向到同一文件

但这种方式输出的是纯文本,Python解析时需要手动处理字符串分割,不如JSON格式高效。

内容的提问来源于stack exchange,提问作者beeeZeee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 05:25:17