Cómo estimar el gas en la creación/implementación del contrato en la blockchain privada de ethereum

Lo que he hecho
a) Cuando uso web3.eth.estimateGaspara estimar el costo de un constructor de creación de contrato sin parámetros, la estimación es correcta.

b) Si el contrato ya está implementado, luego estimar el costo del gas de una función de contrato con parámetros, funciona bien. ( contract.myMethod.estimateGas()usando la API web3)

Problema
a) Cuando estimo el gas en un contrato en el momento de la creación del contrato ( contractObject.new) con un constructor parametrizado, da una estimación incorrecta del costo del gas. ( web3.eth.estimateGasde la API web3)

Lo que quiero
a) Cuando estimo el gas con un constructor de contrato de parámetros múltiples, entonces debería estimar el gas correcto. ( contractObject.newpara llamar al constructor)

b) Browser-soldity proporciona la estimación de gas correcta del contrato con el constructor parametrizado --> antes de crear/implementar el contrato (como el costo de transacción o el costo de ejecución, ¿cómo puedo usar su algoritmo con web3 api para estimar el gas de manera correcta?)

¿Cómo estás usando .estimateGas()? con .getData()?
Matthew Schmidt Estoy usando la función de estimación de gas () con el método de contrato para estimar el gas. no estoy usando ningún método .getData(). por ejemplo: el método contractInstance.myMethod.estimateGas da el resultado correcto. pero quiero estimar contractInstance.new para llamar al constructor con parametrizado. cuando estimoGas de contractInstance.new.estimateGas, da error, ese método no existe. Como arreglarlo

Respuestas (5)

Intenta usar .getData().

.getData()devuelve los parámetros codificados de una función para enviar la transacción manualmente. Luego puede pegar esto web3.eth.estimateGas()(el que está en web3.eth, no en un método dado) para simular el envío de la transacción.

Aquí hay un ejemplo no probado, pero espero que pueda ayudarlo en su camino:

var contractData = contractObject.new.getData(someparam, another, {data: contractBytecode});
var estimate = web3.eth.estimateGas({data: contractData})

Referencias:

web3.eth.estimateGas()

Un ejemplo del uso de .getData() (es la cuarta opción).

¿A qué se refiere 'contractCode' en su primera línea de ejemplo?
¡Vaya! Debería haber sido un poco más claro. Ese es el código de bytes del contrato: lo que obtienes solc --bineditaré mi respuesta.
Este método parece no funcionar con web3 versión 1.0 ya que no hay getData()? Editar: Encontré esta pregunta que dice usar encodeABI()en lugar de getData().

Cuando se trabaja con web3.js versión 1.2.x, no existe el método .getData. La solución que encontré fue estimar el gas del método .deploy(), que efectivamente devuelve el costo de la creación del contrato.

La secuencia de operaciones es:

let contractJSON = // JSON compiled contract
const contractABI = contractJSON.abi;
const bytecode = contractJSON.bytecode;
const contract = new web3.eth.Contract(contractABI);
let options = {
    arguments: [ arg1, arg2,... ],
    data: bytecode
}
const estimatedGas = await contract.deploy(options).estimateGas();

Con web3js, es bastante fácil. Primero necesitas crear tu contrato. Después de la creación, tendrá contractABI y la dirección del contrato de esta manera:

let contractABI = [ { "constant": true, "inputs": [ { "name": "", "type": "bytes32" }, { "name": "", "type": "uint256" } ], "name": "verify", "outputs": [ { "name": "", "type": "address", "value": "0x" } ], "payable": false, "type": "function" }, { "constant": false, "inputs": [ { "name": "document", "type": "bytes32" } ], "name": "sign", "outputs": [], "payable": false, "type": "function" } ]
let contractAddress = '0xaEC9eCDAFAf2404F824B4b7087e9E4F90C77D082'

Con esta información, simplemente cree el contractInstance del proxy del contrato y estime un tx en un método de signo :

const web3conn = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
const contract = web3conn.eth.contract(contractABI)
const contractInstance = contract.at(contractAddress)
let estimatedGas = contractInstance.sign.estimateGas('arg of my function', { from: '0xAddress' })

El proxy es un objeto especial (use un archivo console.log para ver todos los métodos) para facilitar el uso del contrato. Si tiene un método de firma , puede crear un Tx para firmar:

let txHash = contractInstance.sign(param, { from: config.ethereum.identity, gas: estimatedGas })

si usa wan't para llamar a una función (sin transacción):

contractInstance.sign.call(param)
La pregunta es sobre la estimación de gas en la creación de contactos.

Web3 permite esto:

const MyContract = artifacts.require('MyContract');

...

const gas = await MyContract.new.estimateGas(arg1, arg2, arg3);
let contract = new web3.eth.Contract(contractABI);
const bytecodeWithEncodedParameters = contract
    .deploy({
        data: contractByteCode,
        arguments: [?, ?, ?],
    })
    .encodeABI();

const estimateGas = await web3.eth.estimateGas({
    data: bytecodeWithEncodedParameters,
});

Intente así para la implementación de nuevos contratos. Esto funciona para mi.