Contract_ABI 从 API 调用返回有 JSON 接口错误

Contract_ABI returned from API call has JSON interface error

我正在尝试通过从 BSCSCAN 测试网 API 获取合约 ABI 来设置智能合约。我已经成功地从 TESTNET API 获得了 USDT (https://testnet.bscscan.com/address/0x337610d27c682e347c9cd60bd4b3b107c9d34ddd) 的合约 ABI,但是当我尝试设置合约时,我收到了这个错误:

Error: You must provide the json interface of the contract when instantiating a contract object.
    at Contract (C:\Users\User\Documents\Coding Projects\trading-bot - modified\node_modules\web3-eth-contract\src\index.js:70:15)
    at new Contract (C:\Users\User\Documents\Coding Projects\trading-bot - modified\node_modules\web3-eth\src\index.js:149:22)

这是我的异步函数 运行 在 main() 函数中获取 ABI

// Funciton to get the token ABI that uses the BSCSCAN API to get the token you want (IN THIS CASE USDT)
async function getTokenWanted(){
let tokenAddress = '0x337610d27c682e347c9cd60bd4b3b107c9d34ddd';
let tokenWantedAPI = "https://api-testnet.bscscan.com/api?module=contract&action=getabi&address="+tokenAddress+"&apikey=" +process.env.BSCSCAN_API;

        try {
          const res = await fetch(tokenWantedAPI);
          const headerDate = res.headers && res.headers.get('date') ? res.headers.get('date') : 'no response date';
          console.log('Status Code:', res.status);
          console.log('Date in Response header:', headerDate);
          let users = await res.json();
          contractABI =users.result;

          return contractABI
        } catch (err) {
          console.log(err.message); //can be console.error
        }
}

// Function to setup the token contract 
async function setupTokenWantedContract(){
  let contract_ABI = await getTokenWanted();
  console.log(contract_ABI);
  let token_Address ='0x337610d27c682e347c9cd60bd4b3b107c9d34ddd';
  const tokenContract = new web3.eth.Contract(contract_ABI, token_Address);
  
  return tokenContract;
}

这些函数运行在主函数中是这样的:

async function main(){

let tokenWantedContract = awaitsetupTokenWantedContract()

}

登录到控制台时收集的 ABI 合同是这样的 (这与您在 bscscan 中转到合同 ABI 并将其复制并粘贴到代码中时完全相同,但是我会想要动态地执行此操作因此我使用 API):

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"_decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] 

以下是我到目前为止尝试过的方法:

感谢任何帮助,因为我是编码 web3 的新手,并且认为这将是一个有趣的项目!谢谢!

显然,当我在这个代码块上使用 JSON.Parse 时,我以某种方式让它工作:

// Funciton to get the token ABI that uses the BSCSCAN API to get the token you want (IN THIS CASE USDT)
async function getTokenWanted(){
let tokenAddress = '0x337610d27c682e347c9cd60bd4b3b107c9d34ddd';
let tokenWantedAPI = "https://api-testnet.bscscan.com/api?module=contract&action=getabi&address="+tokenAddress+"&apikey=" +process.env.BSCSCAN_API;

        try {
          const res = await fetch(tokenWantedAPI);
          const headerDate = res.headers && res.headers.get('date') ? res.headers.get('date') : 'no response date';
          console.log('Status Code:', res.status);
          console.log('Date in Response header:', headerDate);
          let users = await res.json();
          contractABI =JSON.parse(users.result);

          return contractABI
        } catch (err) {
          console.log(err.message); //can be console.error
        }
}

奇怪,我第一次尝试 JSON.Parse() 时一定是出了什么问题。