I get this error when doing a transaction through Metamask and a NextJS application using this Solidity contract:
The error:
Error: cannot estimate gas; transaction may fail or may require manual gas limit
[ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ]
(reason="execution reverted", method="estimateGas", transaction=
{"from":"0x80CB17D85034EDb2Ea1D4BC7d9d512c5dD0d6000",
"to":"0x9d3cA4786e3584b198400F82CA883A581Bd3c4C0","value":{"type":"BigNumber","hex":"0x057289b00c97"},
"data":"0xde905f830000000000000000000000000000000000000000000000000000000000000060000000000000000000000000c99da3a663604c43f6296f3f95e9ea7b6481f01f000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00000000000000000000000000000000000000000000000000000000000000143956764a6a6c33674a726f6b6762767a456d4e64000000000000000000000000","accessList":null}, error={"code":-32603,"message":"Internal JSON-RPC error.","data":{"code":-32000,"message":"execution reverted"},"stack":"{\n \"code\": -32603,\n \"message\": \"Internal JSON-RPC error.\",\n \"data\": {\n \"code\": -32000,\n \"message\": \"execution reverted\"\n }
Solidity Code:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
// Import this file to use console.log
import "hardhat/console.sol";
contract CryptoPayments {
using SafeMath for uint256;
uint256 public ownerPercentage;
address payable public owner;
event NewPayment(string txId, address from, address to, address token, uint256 when);
constructor() payable {
owner = payable(msg.sender);
ownerPercentage = 5;
}
function createPayment(string memory txId, address payable seller, address token) public payable {
uint256 ownerPortion = msg.value.mul(ownerPercentage).div(100);
uint256 sellerPortion = msg.value - ownerPortion;
IERC20 _token = IERC20(token);
_token.transferFrom(msg.sender, address(this), msg.value);
_token.transfer(owner, ownerPortion);
_token.transfer(seller, sellerPortion);
emit NewPayment(txId, msg.sender, seller, token, block.timestamp);
}
function setOwnerPercentage(uint256 percentage) public {
require(msg.sender == owner, "You aren't the owner");
ownerPercentage = percentage;
}
function setOwner(address newOwner) public {
require(msg.sender == owner, "You aren't the owner");
owner = payable(newOwner);
}
}
JS code responsible for the execution:
const [ token, setToken ] = useState({
bnb: {
name: 'WBNB',
selected: false,
address: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
},
});
const contractAddr = "<CONTRACT_ADDR_HERE>"
const trxData = {seller_wallet_address: "<WALLET_ADDRESS_HERE>"}
async function initiatePayment(){
const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
let tokenAbi = ["function approve(address _spender, uint256 _value) public returns
(bool success)"];
let tokenContract = new ethers.Contract(token['bnb'].address, tokenAbi, signer);
await tokenContract.approve(contractAddr, value);
const contract = new ethers.Contract(contractAddr, ctrct.abi, signer)
const val = await contract.createPayment(id, trxData.seller_wallet_address,
token['bnb'].address, {value});
}
payablemodifier but later using ERC20 transfer?msg.valueif you aren't accepting ether. Add anamountparameter instead. I don't seen an evident error, try debugging step by step, make sure the account has enough token balance to operate.