Gasschätzung für die Kartenaktualisierung mit web3js

Die Gasschätzung für die Vertragsbereitstellung mit web3js sieht folgendermaßen aus:

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

Zum Beispiel habe ich die einfache Zuordnung mapping(string => string)und updateMappingFunktion, um Zuordnungsschlüssel/Wert-Paare im Vertrag festzulegen. Ich möchte es aktualisieren:

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

Wie kann man Gas für eine solche Transaktion mit web3js schätzen?

{from:web3.eth.accounts[0], data: ***, gas:gasEstimate, value: ***}, function(e, contract){
Wenn Sie Ihren Vertrag im Solidity-Browser bereitstellen, zeigt er das geschätzte Gas für jede Methode an.

Antworten (1)

Mit web3 1.0.x und mit Vertrag 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});
}

Mit web3 1.0.x und ohne ABI Vertrag :

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
  });
}

Mit web3 0.x (etwas kompliziert, aber funktioniert) :

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
}