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

使用TronWeb与TRON智能合约交互时遇调用回滚错误求助

问题排查:TronWeb调用Solidity合约hello方法报错

问题背景

部署了如下HelloWorld Solidity智能合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract HelloWorld {
    function hello() public pure returns (string memory) {
        return "Hello, World!";
    }
}

编写了TronWeb交互代码:

var TronWeb = require('tronweb');
var tronWeb = new TronWeb({
    fullHost: 'http://localhost:26667',
    privateKey: 'xxxxxxx'
});

async function fetchAbi(contractAddress) {
    try {
        let contractInfo = await tronWeb.trx.getContract(contractAddress);
        return contractInfo.abi; // Return the ABI
    } catch (error) {
        console.error("Error in fetchAbi function:", error);
        throw error; // Rethrow to handle it in the caller
    }
}

async function main(abiData) {
    try {
        let contractAddress = 'TYiwthLXHcarLqRxWA5FKT1NgJicLCanhK';
        // Ensure the property name used here matches what fetchAbi returns. It seems it should be `abi`, not `entrys`.
        let actualAbi = abiData.entrys; // Adding a fallback in case the property name is different
        //let realabi = [{"outputs":[{"type":"string"}],"name":"hello","stateMutability":"Pure","type":"Function"}]
        let contract = await tronWeb.contract(actualAbi, contractAddress);
        let result = await contract.hello().call();
        console.log(result);
    } catch (error) {
        console.error("Error in main function:", error);
    }
}

(async () => {
    try {
        const contractAddress = 'TGTMtrSkN41e49vBNTBRifAm9PbXfEuhQi';
        const abi = await fetchAbi(contractAddress);
        console.log(abi)
        await main(abi);
    } catch (error) {
        console.error("Error in executing main with fetched ABI:", error);
    }
})();

执行后输出的ABI信息:

{
  entrys: [ { name: 'hello', stateMutability: 'View', type: 'Function' } ]
}

但调用时报错:Error in main function: The call has been reverted or has thrown an error,已确认合约地址正确,请求排查问题。

问题分析与修复方案

1. ABI信息不完整

从输出的ABI可以看到,hello方法缺少outputs定义,而Solidity合约中该方法明确返回string类型。TronWeb需要完整的ABI才能正确编码/解码合约调用,缺失返回值定义会导致调用失败。

另外,Solidity中pure修饰的方法,在ABI里stateMutability应该是Pure,但返回的ABI显示为View,这也会导致方法匹配异常。

2. 合约地址不一致

代码中存在两个不同的合约地址:

  • 自执行函数中传入fetchAbi的地址是TGTMtrSkN41e49vBNTBRifAm9PbXfEuhQi
  • main函数中使用的调用地址是TYiwthLXHcarLqRxWA5FKT1NgJicLCanhK
    必须确保两个地址一致,否则调用的是不同合约,必然报错。

修复后的代码示例(推荐方案)

直接使用完整的手动ABI,避免节点返回不完整ABI的问题:

var TronWeb = require('tronweb');
var tronWeb = new TronWeb({
    fullHost: 'http://localhost:26667',
    privateKey: 'xxxxxxx'
});

// 完整ABI,包含返回值定义和正确的stateMutability
const fullAbi = [
    {
        "outputs": [{"type": "string"}],
        "name": "hello",
        "stateMutability": "Pure",
        "type": "Function"
    }
];

async function main() {
    try {
        // 使用统一的合约地址
        const contractAddress = 'TGTMtrSkN41e49vBNTBRifAm9PbXfEuhQi';
        let contract = await tronWeb.contract(fullAbi, contractAddress);
        let result = await contract.hello().call();
        console.log(result); // 应输出 "Hello, World!"
    } catch (error) {
        console.error("Error in main function:", error);
    }
}

(async () => {
    await main();
})();

备选方案:修复ABI获取逻辑

如果坚持通过节点获取ABI,可在代码中补全缺失的字段并统一地址:

var TronWeb = require('tronweb');
var tronWeb = new TronWeb({
    fullHost: 'http://localhost:26667',
    privateKey: 'xxxxxxx'
});

async function fetchAbi(contractAddress) {
    try {
        let contractInfo = await tronWeb.trx.getContract(contractAddress);
        // 补全hello方法的outputs定义并修正stateMutability
        contractInfo.abi.entrys.forEach(entry => {
            if (entry.name === 'hello') {
                entry.outputs = [{"type": "string"}];
                entry.stateMutability = "Pure";
            }
        });
        return contractInfo.abi;
    } catch (error) {
        console.error("Error in fetchAbi function:", error);
        throw error;
    }
}

async function main(abiData) {
    try {
        // 使用和fetchAbi一致的合约地址
        const contractAddress = 'TGTMtrSkN41e49vBNTBRifAm9PbXfEuhQi';
        let actualAbi = abiData.entrys;
        let contract = await tronWeb.contract(actualAbi, contractAddress);
        let result = await contract.hello().call();
        console.log(result);
    } catch (error) {
        console.error("Error in main function:", error);
    }
}

(async () => {
    try {
        const contractAddress = 'TGTMtrSkN41e49vBNTBRifAm9PbXfEuhQi';
        const abi = await fetchAbi(contractAddress);
        await main(abi);
    } catch (error) {
        console.error("Error in executing main with fetched ABI:", error);
    }
})();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:42:41