Search code examples
javascriptsoliditysmartcontractsweb3jschainlink

Communicating with a Smart Contract on BSC over ethers gives -32603 error code


Hello I am new to Smart Contract development, for a few days I try to get this working, but no luck. I hope someone can help me. I try to communicate to a Smart Contract deployed to BSC https://testnet.bscscan.com/address/0x2ED1c3c1Fc6646F321cf546a892684E946435CE9 see the source code below.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract FundMe {

    mapping(address => uint256) public addressToAmountFunded;
    address[] public funders;
    address public owner;
    AggregatorV3Interface internal priceFeed;
    uint balance;
    
    // if you're following along with the freecodecamp video
    // Please see https://github.com/PatrickAlphaC/fund_me
    // to get the starting solidity contract code, it'll be slightly different than this!
    constructor(address _priceFeed) {
        priceFeed = AggregatorV3Interface(_priceFeed);
        owner = msg.sender;
    }

    function fund() public payable {
        uint256 mimimumUSD = 50 * 10**18;
        require(
            getConversionRate(msg.value) >= mimimumUSD,
            "You need to spend more ETH!"
        );
        addressToAmountFunded[msg.sender] += msg.value;
        balance += msg.value;
        funders.push(msg.sender);
    }

    function getVersion() public view returns (uint256) {
        return priceFeed.version();
    }

    function getPrice() public view returns (uint256) {
        (, int price, , , ) = priceFeed.latestRoundData();
        return uint256(price * 10000000000);
    }

    // 1000000000
    function getConversionRate(uint256 ethAmount)
        public
        view
        returns (uint256)
    {
        uint256 ethPrice = getPrice();
        uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
        return ethAmountInUsd;
    }

    function getEntranceFee() public view returns (uint256) {
        // mimimumUSD
        uint256 mimimumUSD = 50 * 10**18;
        uint256 price = getPrice();
        uint256 precision = 1 * 10**18;
        return (mimimumUSD * precision) / price;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function withdraw() public payable onlyOwner {
        payable(msg.sender).transfer(balance);

        for (
            uint256 funderIndex = 0;
            funderIndex < funders.length;
            funderIndex++
        ) {
            address funder = funders[funderIndex];
            addressToAmountFunded[funder] = 0;
        }
        funders = new address[](0);
    }
}

I deployed the smart contract with truffle, with the following migration script

const FundMe = artifacts.require("FundMe");
const BINANCE_BNB_USD_PRICE_FEED = '0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE';

module.exports = async (deployer, network, [defaultAccount]) => {

  let priceFeedAddress = BINANCE_BNB_USD_PRICE_FEED
  try {
      await deployer.deploy(FundMe, BINANCE_BNB_USD_PRICE_FEED, { from: defaultAccount })
  } catch (err) {
      console.error(err)
  }
}

I try to call getPrice() that communicates to chainlink to get the latest price of BNB/USDT.

Here is the Javascript

const getContract = () =>
  new Promise(async (resolve, reject) => {
    const contract = await fetch('./build/contracts/FundMe.json')
    const Contract = await contract.json()

    let provider = await detectEthereumProvider()
    if (provider) {
      await provider.request({ method: 'eth_requestAccounts' })
      const networkId = await provider.request({ method: 'net_version' })
      
      provider = new ethers.providers.Web3Provider(provider)
      const signer = provider.getSigner()
      showAddress(signer)

      const contract = new ethers.Contract(
        Contract.networks[networkId].address,
        Contract.abi,
        signer,
      )
      resolve(contract)
      return
    }
    reject('Install Metamask')
  })

const showAddress = async (signer) => {
    address = await signer.getAddress()
    const connectButton = document.getElementById('connect')
    connectButton.innerText = address
}

const getPrice = async (contract) => {
    console.log('contract', contract)
    const price = await contract.getPrice()
    console.log('price', price)
    const priceContainer = document.getElementById('price')
    priceContainer.innerText = price
}

const init = async () => {
    const contract = await getContract()
    getPrice(contract)
}

const fundButton = document.getElementById('fund')
fundButton.addEventListener('click', async () => {
    const fundMe = await getContract()
})

init()

I get the following error in the browser console and have no idea whats the cause. Console error


Solution

  • Your deploy script passing the 0x056... address as the priceFeed param of the constructor.

    So the getPrice() contract function is then trying to call the latestRoundData() on the 0x056... address, expecting a response.

    However, your contract is deployed on the testnet, and there's no contract on the 0x056... address on the testnet (link) to return a value, which causes the "main" call to revert.