You usually get that error when code execution fails, this can be because of regular execution or because one of the reverts is catching an error, in your case, problem were the reverts, here is how you can find out:
This feature is not yet on nodes, only in in javascriptVM which you can use in remix, or in your truffle tests/ganache, but it's recommended that you start using it now; you can add an error message to your reverts, this is the easiest way to get better comprehensive errors, IE:
require(condition, "string returned if condition fails");
Note that I'm using javascript vm for this example instead of injected web3.
When I execute your code, the first error we can find is in the second require:
require(block.number > drawing.drawBlock, "Can't draw yet");
We can't draw until some blocks have passed, I forced the generation of some blocks in the VM by calling other functions, if you are doing this on ethereum, you just need to wait.
After solving this problem, it crashed in the next line:
require(drawing.entries.length > 0, "No entries for that round");
So I called buy() a couple of times sending the amount of ether specified in TICKET_PRICE, then I checked that the entries where added by calling rounds(numberOfRound), and after calling drawWinner(numberOfRound) with a valid round, the function worked correctly.
You should create a call that will tell you if that function will work or it will fail by checking those conditions, that way you can solve a ton of headaches, remember to put error messages on require, and if you want to see everything step by step, the debugger provided in remix is pretty useful.
TLDR: For your code to work, you need to make sure that enough blocks have passed, and that the round has at least one entry.
By the way, there are a couple of vulnerabilities in your drawWinner() function, don't use it on production!
Best Answer
Among other things, every Ethereum transaction has attribute named
gasLimit
or simplygas
. This is the maximum amount of gas transaction is allowed to consume. When sending transaction via Web3 API, you may specify value for this attribute explicitly:This parameter is optional, and if it is omitted, Web3 API implementation will try to estimate proper value by first executing transaction locally before actually broadcasting it to the network. This local execution is similar to how miners execute transaction before including them into blocks.
In case local execution succeeds, Web3 API implementation counts how much gas transaction actually consumed and uses this value to populate
gasLimit
parameter. Though, in case local execution failed, e.g. smart contract reverted it,gas estimation failed
error is reported. You may still broadcast such transaction by explicitly specifyinggasLimit
for it.