├── package.json ├── tsconfig.json ├── .gitignore ├── scripts └── deploy.ts ├── contracts └── EventWinner.sol ├── LICENSE ├── hardhat.config.ts └── README.md /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomicfoundation/hardhat-toolbox": "^5.0.0", 5 | "hardhat": "^2.22.16" 6 | }, 7 | "dependencies": { 8 | "dotenv": "^16.4.5" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | 4 | # Hardhat files 5 | /cache 6 | /artifacts 7 | 8 | # TypeChain files 9 | /typechain 10 | /typechain-types 11 | 12 | # solidity-coverage files 13 | /coverage 14 | /coverage.json 15 | 16 | # Hardhat Ignition default folder for deployments against a local node 17 | ignition/deployments/chain-31337 18 | -------------------------------------------------------------------------------- /scripts/deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'hardhat' 2 | 3 | async function main() { 4 | const [deployer] = await ethers.getSigners(); 5 | 6 | const EventWinner = await ethers.getContractFactory("EventWinner"); 7 | const eventWinner = await EventWinner.deploy(); 8 | await eventWinner.waitForDeployment(); 9 | 10 | console.log(`EventWinner deployed to: ${await eventWinner.getAddress()}`); 11 | 12 | const winnerContractAddress = "0xcF469d3BEB3Fc24cEe979eFf83BE33ed50988502"; 13 | const tx = await eventWinner.callWinner(winnerContractAddress); 14 | 15 | console.log("Transaction hash:", tx.hash); 16 | } 17 | 18 | main() 19 | .then(() => process.exit(0)) 20 | .catch(error => { 21 | console.error(error) 22 | process.exitCode = 1 23 | }) 24 | -------------------------------------------------------------------------------- /contracts/EventWinner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.27; 3 | 4 | interface ContractWinner { 5 | function attempt() external; 6 | } 7 | 8 | contract EventWinner { 9 | event AttemptMade(address indexed targetContract, bool success); 10 | 11 | function callWinner(address winnerContractAddress) external { 12 | require(winnerContractAddress != address(0), "Invalid contract address"); 13 | 14 | // Call the attempt function and capture the success 15 | (bool success,) = winnerContractAddress.call( 16 | abi.encodeWithSignature("attempt()") 17 | ); 18 | 19 | // Emit event with the result 20 | emit AttemptMade(winnerContractAddress, success); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 MARK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import { HardhatUserConfig } from "hardhat/config"; 2 | import "@nomicfoundation/hardhat-toolbox"; 3 | import "dotenv/config"; 4 | 5 | const infuraKey: string = process.env.INFURA_API_KEY as string; 6 | const privateKey: string = process.env.PRIVATE_KEY ? process.env.PRIVATE_KEY as string: ""; 7 | const etherscanKey: string = process.env.ETHERSCAN_KEY ? process.env.ETHERSCAN_KEY as string: ""; 8 | 9 | const config: HardhatUserConfig = { 10 | solidity: { 11 | version: "0.8.27", 12 | settings: { 13 | optimizer: { 14 | enabled: true, 15 | runs: 100, 16 | }, 17 | // viaIR: true, 18 | }, 19 | }, 20 | networks: { 21 | sepolia: { 22 | url: `https://sepolia.infura.io/v3/${infuraKey}`, 23 | accounts: [`0x${privateKey}`], 24 | }, 25 | mainnet: { 26 | url: `https://mainnet.infura.io/v3/${infuraKey}`, 27 | accounts: [`0x${privateKey}`], 28 | }, 29 | hardhat: { 30 | chainId: 31337, 31 | }, 32 | }, 33 | etherscan: { 34 | apiKey: { 35 | mainnet: etherscanKey, 36 | sepolia: etherscanKey 37 | }, 38 | }, 39 | gasReporter: { 40 | enabled: true, 41 | }, 42 | sourcify: { 43 | enabled: true, 44 | }, 45 | }; 46 | 47 | export default config; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EventWinner Smart Contract 2 | 3 | A Solidity smart contract implementation that demonstrates external contract interaction on the Ethereum blockchain. 4 | 5 | This is the answer to stackoverflow question: [Error: cannot estimate gas; transaction may fail or may require manual gas limit (Sepolia test Network) 6 | ](https://stackoverflow.com/questions/79231971/error-cannot-estimate-gas-transaction-may-fail-or-may-require-manual-gas-limit) 7 | 8 | ## Overview 9 | 10 | The EventWinner project showcases a smart contract that can interact with other contracts through their interfaces. It implements a pattern for making external calls to contracts that expose an `attempt()` function. 11 | 12 | ## Technical Stack 13 | 14 | - Solidity ^0.8.27 15 | - Hardhat 16 | - TypeScript 17 | - Ethers.js 18 | 19 | ## Contract Architecture 20 | 21 | ### EventWinner.sol 22 | The main contract contains: 23 | - Interface definition for target contracts 24 | - External function to interact with other contracts 25 | - Low-level call implementation for robust contract interaction 26 | 27 | ### Key Features 28 | - External contract interaction 29 | - Interface-based calling 30 | - Gas-efficient implementation 31 | - Error handling 32 | 33 | ## Usage 34 | 35 | The contract can be used to interact with any contract that implements the `attempt()` function: 36 | 37 | ```bash 38 | // Get contract instance 39 | const eventWinner = await EventWinner.deploy(); 40 | 41 | // Call target contract 42 | await eventWinner.callWinner(targetContractAddress); 43 | ``` 44 | 45 | ## Development 46 | 47 | 1. Clone the repository 48 | ```bash 49 | git clone 50 | ``` 51 | 2. Install dependencies: 52 | ```bash 53 | npm install 54 | ``` 55 | 3. Compile contracts: 56 | ```bash 57 | npx hardhat compile 58 | ``` 59 | 4. Run deployment script: 60 | ```bash 61 | npx hardhat run scripts/deploy.ts --network sepolia 62 | ``` 63 | 64 | ## Network support 65 | 66 | - Sepolia 67 | - Local hardhat Network 68 | 69 | ## License 70 | This project is licensed under the MIT License. --------------------------------------------------------------------------------