6

The gas estimation for contract deploying with web3js will look like:

var res = web3.eth.estimateGas({
    from: web3.eth.defaultAccount, 
    data: contractByteCode
});

For example, I have the simple mapping mapping(string => string) and updateMapping function to set mapping key/value pair in contract. I want to update it:

var contract = web3.eth.contract(contractABI).at(contractAddress);
contract.updateMapping.sendTransaction(
   foo, bar, 
   {gas: estimatedGas, from: web3.eth.defaultAccount}, 
   function(err, result) {
});

How to estimate gas for such transaction with web3js?

2
  • {from:web3.eth.accounts[0], data: ***, gas:gasEstimate, value: ***}, function(e, contract){
    – Badr Bellaj
    Commented Dec 28, 2016 at 11:27
  • 1
    When you deploy your contract inside solidity browser, it shows the estimated gas for the each method.
    – alper
    Commented Dec 30, 2016 at 1:07

1 Answer 1

5

With web3 1.0.x and with contract ABI:

const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

estimate();

async function estimate() {
  const contractAddress = "0x...";
  const contractABI = [...]
  const contract = new web3.eth.Contract(contractABI, contractAddress)
  const estimatedGas = await estimateGas(contract, "foo", "bar");
  console.log("estimatedGas:",estimatedGas)
}

async function estimateGas(contract, key, value) {
  return await contract.methods.updateMapping(key, value).estimateGas({from: web3.eth.defaultAccount});
}

With web3 1.0.x and without ABI of contract:

const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

estimate();

async function estimate() {
  const contractAddress = "0x...";
  const estimatedGas = await estimateGas(contractAddress, "foo", "bar");
  console.log("estimatedGas:",estimatedGas)
}

async function estimateGas(contractAddress, key, value) {
  const methodSignature = web3.eth.abi.encodeFunctionSignature('updateMapping(string,string)')
  const abiEncodedParams = web3.eth.abi.encodeParameters(["string", "string"], [key, value]).substr(2)
  const methodByteCode = methodSignature + abiEncodedParams;

  return await web3.eth.estimateGas({
    from: web3.eth.defaultAccount, 
    data: methodByteCode,
    to: contractAddress
  });
}

With web3 0.x (a little bit comlicated but works):

var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
web3.eth.defaultAccount = web3.eth.accounts[0];

var contractAddress = "0x...";
var estimatedGas = estimateGas(web3, contractAddress, "foo", "bar");

function estimateGas(web3, contractAddress, key, value) {
   var funcStr = "updateMapping(string,string)";
   var funcHex = hexEncode(funcStr);
   var funcEncoded = web3.sha3(funcHex);
   var funcEncodePart = funcEncoded.substring(0,10);

   var keyHex = hexEncode(key);
   var keyLengthHex = toUnifiedLength(key.length.toString(16));

   var valueHex = hexEncode(value);
   var valueLengthHex = toUnifiedLength(value.length.toString(16));

   var compiled = funcEncodePart + keyLengthHex + keyHex + valueLengthHex + valueHex;
   var estimatedGas = web3.eth.estimateGas({
    from: web3.eth.defaultAccount, 
    data: compiled,
    to: contractAddress
   });
   return estimatedGas;
}

function toUnifiedLength(strIn) {
  var strOut = "";
  for (var i = 0; i < 64 - strIn.length; i++) {
    strOut += "0"
  }
  strOut += strIn;
  return strOut;
}

function hexEncode(str) {
  var hex, i;

  var result = "";
  for (i=0; i<str.length; i++) {
    hex = str.charCodeAt(i).toString(16);
    result += hex.slice(-4);
  }

  return result
}

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.