6

I'm trying to estimate gas cost of a contract call, i need to send a string to a contract, but i need to see if i overtook the GAS limit.

I'm trying like this:

    Transaction t = Transaction.createContractTransaction(myAddress, BigInteger.valueOf(100), gasPrice, gasLimit, null, "0123456789");
    EthEstimateGas eg = web3j.ethEstimateGas(t).send();
    System.out.println("EstimateGas: " + eg.getAmountUsed().toByteArray());

But i receive the error:

Erro: org.web3j.exceptions.MessageDecodingException: Value must be in format 0x[1-9]+[0-9]* or 0x0

2 Answers 2

4
  1. You need to encode the data by using FunctionEncoder.encode
  2. Before checking the result you need to check for errors. If an error (for example a contract error) is returned the result will be null and you will get the the error you described.

Do something like this:

Function function = new Function("nameOfFunction", ...)
Transaction tx = Transaction.createFunctionCallTransaction(..., FunctionEncoder.encode(function));
EthEstimateGas gasEstimate = client.ethEstimateGas(tx).send();
if (gasEstimate.hasError()) {
  logger.info("Contract error: {}", gasEstimate.getError().getMessage());
} else {
  logger.info("Gas estimate: {}", gasEstimate.getAmountUsed()); // will throw in case of error
}
2

What you are doing is sending a message to the contract (which needs to be hex-encoded). In this case, you want the message to say 'execute function with the following params'.

Take a look at FunctionEncoder.encode that should give you what you need.

3
  • In this case, i need to put the hex on Transaction creation in my code example?
    – SkyWorker
    Commented Oct 22, 2019 at 13:56
  • Exactly, take the encoded output from the function encoder and pass it into the transaction. Commented Oct 24, 2019 at 8:46
  • @AntonyDenyer So this looks really good and my version compiles but the EthEstimateGas object has a getResult() that yields null and causes an exception in getAmountUsed(). I build my function with Function("name", Array of inputs, Array of outputs) then do String txData = FunctionEncoder.encode() and pass it as the last arg. The contract exists at address 0x... because a generated wrapper method can hit it and get results. I am connecting to the local geth --dev node. Any quick clues...? Commented Sep 22, 2020 at 23:04

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.