I will summarise my question. I have first deployed successfully the smart contract from my account address in Sepolia test network. Then, when I wanted to call a function of that deployed contract, I have this error: "cannot estimate gas; transaction may fail or may require manual gas limit". "UNPREDICTABLE_GAS_LIMIT" The parameter of the function that I want to call is a deployed contract address that implement a Interface.
I have tried to fix this problem on my own searching on the internet, but I couldn't. I have tried to add a gas limit manually to the transection, but it did not work. I used Hardhat for this project and maybe something is wrong with the configuration. Please, help!
"Deploy.js" file:
const hre = require("hardhat");
const ethers = hre.ethers;
async function main() {
// The address of the winner contract that we want to call
const winnerContractAddress = "0xcF469d3BEB3Fc24cEe979eFf83BE33ed50988502";
// Get the EventWinner contract factory from the hardhat config
const EventWinner = await hre.ethers.getContractFactory("EventWinner");
// Deploy the EventWinner contract to the blockchain
const eventWinner = await EventWinner.deploy();
// Wait for the contract to be deployed
await eventWinner.deployed();
// Log the address of the deployed contract to the console
console.log(`contract is deployed to ${eventWinner.address}`);
// Call the callWinner function of the EventWinner contract and pass in the address of the winner contract
const tx = await eventWinner.callWinner(winnerContractAddress);
// Wait for the transaction to be confirmed on the blockchain
await tx.wait();
}
// Call the main function and catch any errors
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
"Contract.sol" file:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;
interface ContractWinner{
function attempt()external;
}
contract EventWinner{
// Function to call the attempt function on the ContractWinner instance at the given address
function callWinner(address winnerContractAddress) external{
ContractWinner(winnerContractAddress).attempt();
}
}
"hardhat.config.js" file:
require("dotenv").config();
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.27",
networks: {
sepolia: {
url: process.env.RPC_URL,
accounts: [process.env.PRIVATE_KEY]
},
},
etherscan: {
apiKey: {
sepolia: process.env.ETHERSCAN_API_KEY,
},
},
};
You need to use low-level call()
function instead of direct attempt()
function.
The call()
function with abi.encodeWithSignature()
ensures the function call is properly encoded and sent to the target contract, increasing the chances of successful execution.
This is what I have just done. https://sepolia.etherscan.io/address/0x333BA72B7b3736e310B325cBEDBAd8e9Af752648#code
Please check. You can find updated contract file there, and can call the function.
And this is the deploy.ts script.
import { ethers } from 'hardhat'
async function main() {
const [deployer] = await ethers.getSigners();
const EventWinner = await ethers.getContractFactory("EventWinner");
const eventWinner = await EventWinner.deploy();
await eventWinner.waitForDeployment();
console.log(`EventWinner deployed to: ${await eventWinner.getAddress()}`);
const winnerContractAddress = "0xcF469d3BEB3Fc24cEe979eFf83BE33ed50988502";
const tx = await eventWinner.callWinner(winnerContractAddress);
console.log("Transaction hash:", tx.hash);
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error)
process.exitCode = 1
})