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

ERC20代币授权异常问题:如何将授权支出方从本地测试网站切换为1inch DEX

问题分析与解决方案

首先,我们来拆解你遇到的两个核心问题:

1. 授权对象错误的根本原因:链ID不匹配

你的代码中存在链ID不一致的关键问题:

  • 你调用1inch健康检查接口时用的是BSC链ID(56),但获取授权spender地址、代币列表和calldata时,却用了以太坊主网的链ID(1)。
  • 你的目标代币PPAY(0x0a50c93c762fdd6e56d86215c24aaad43ab629aa)是部署在BSC上的,必须使用BSC对应的1inch API端点,否则生成的calldata会指向以太坊主网的1inch地址,甚至导致授权逻辑完全错误。

2. 对Metamask提示的误解

Metamask显示“Allow Http://localhost:1234 to spend your PPAY”是正常的提示逻辑:它只是告诉你发起授权请求的网站是本地测试站,但实际被授权的支出方是包含在交易data字段里的合约地址(也就是1inch的地址)。只要calldata正确,授权对象就是1inch,而非你的本地网站。


修改步骤

步骤1:统一所有1inch API的链ID为BSC(56)

将代码中所有1inch API路径里的1替换为56,确保和你的代币所在链一致:

// 原错误代码(链ID=1,以太坊主网)
// let url1 = "https://api.1inch.exchange/v3.0/1/approve/spender";
// let url2 = "https://api.1inch.exchange/v3.0/1/tokens";
// let url3 = "https://api.1inch.exchange/v3.0/1/approve/calldata?amount="+amount+"&tokenAddress="+selected_coin;

// 修改后(链ID=56,对应BSC)
let url1 = "https://api.1inch.exchange/v3.0/56/approve/spender";
let url2 = "https://api.1inch.exchange/v3.0/56/tokens";
let url3 = "https://api.1inch.exchange/v3.0/56/approve/calldata?amount="+amount+"&tokenAddress="+selected_coin;

步骤2:添加链ID检查(可选但推荐)

在发起交易前,检查用户钱包当前连接的链是否为BSC,避免因链不匹配导致交易失败:

// 在approveTokenSpent函数开头添加
const currentChainId = await ethereum.request({ method: 'eth_chainId' });
// BSC的链ID十六进制为0x38
if (currentChainId !== '0x38') {
    alert('请切换到BSC网络后再操作');
    return;
}

步骤3:验证生成的calldata(调试用)

在获取transactionParameters后,打印data字段,确认其中包含BSC的1inch授权地址(0x1111111254EEB25477B68fb85Ed929f73A960582):

const transactionParameters = await fetch(url3)
    .then(res => res.json())
    .then(data1 => {
        console.log("生成的calldata: ", data1.data);
        const transactionParameters = {
            to: data1['to'],
            from: user_address[0],
            value: "0",
            data: data1['data']
        };
        return transactionParameters
    });

修改后的完整代码片段(关键部分)

approveTokenSpent = async () => { 
    console.log("Approve v1"); 
    const user_address = await checkEthereumAddress(); 
    console.log(user_address); 

    // 新增:检查当前链是否为BSC
    const currentChainId = await ethereum.request({ method: 'eth_chainId' });
    if (currentChainId !== '0x38') {
        alert('请切换到BSC网络后再操作');
        return;
    }

    const selected_coin = document.getElementById("select_coin1").value; 
    var amount = document.getElementById("amount1").value; 
    amount = amount * 1000000000000000000; 
    console.log("SELECTED COIN " + selected_coin + " AMOUNT " + amount); 

    let url = "https://api.1inch.exchange/v3.0/56/healthcheck"; 
    answer = await urlSend(url); 
    console.log("1inch status: "); 
    if(answer.status === "OK") { 
        console.log(answer.status); 
        // 修改:使用BSC链ID的API
        let url1 = "https://api.1inch.exchange/v3.0/56/approve/spender"; 
        let url2 = "https://api.1inch.exchange/v3.0/56/tokens"; 
        console.log(url1); 
        const address_spender = await fetch(url1)
            .then( res => res.json() ) 
            .then( data => { console.log(data); return data }); 
        console.log(url2); 
        const tokens = await fetch(url2) 
            .then( res => res.json() ) 
            .then( data => { console.log(data); return data }); 
        console.log(tokens.tokens["0x0a50c93c762fdd6e56d86215c24aaad43ab629aa"]); 
        address_spender_new = address_spender["address"] 
        console.log(address_spender["address"]); 
        console.log(typeof(address_spender_new)); 
        // 修改:使用BSC链ID的calldata API
        let url3 = `https://api.1inch.exchange/v3.0/56/approve/calldata?amount=${amount}&tokenAddress=${selected_coin}`; 
        console.log("URL3 before tp"); 
        console.log(url3); 
        const transactionParameters = await fetch(url3) 
            .then( res => res.json() ) 
            .then( data1 => { 
                console.log("url3 data: ", data1); 
                // 调试:打印calldata确认spender地址
                console.log("calldata: ", data1.data);
                const transactionParameters = { 
                    to: data1['to'], 
                    from: user_address[0], 
                    value: "0", 
                    data: data1['data'] 
                }; 
                return transactionParameters 
            }); 
        try { 
            const txHash = await ethereum.request({ 
                method: 'eth_sendTransaction', 
                params: [transactionParameters], 
            }); 
            console.log("交易哈希: ", txHash);
        } catch (error) { 
            if (error.code === 4001) { 
                alert("用户拒绝了交易签名。") 
            } else { 
                alert(`交易错误: ${error.message}`) 
            } 
        } 
        return address_spender 
    } else { 
        console.log(answer.status); 
    } 
}

验证修改效果

修改完成后:

  1. 确保钱包切换到BSC网络;
  2. 发起授权请求,Metamask仍会显示“localhost:1234发起请求”,但实际授权的支出方是1inch的BSC合约地址;
  3. 你可以在BSC浏览器上查询该代币的allowance方法,验证授权对象是否为1inch的地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:27:29