So schätzen Sie das Gas bei der Vertragserstellung/Bereitstellung in der privaten Ethereum-Blockchain

Was ich getan habe
a) Wenn ich web3.eth.estimateGasdie Kosten eines Vertragserstellungskonstrukteurs ohne Parameter schätze, ist die Schätzung korrekt.

b) Wenn der Vertrag bereits bereitgestellt ist, funktioniert das Schätzen der Gaskosten einer Vertragsfunktion mit Parametern einwandfrei. ( contract.myMethod.estimateGas()mit der web3-API)

Problem
a) Wenn ich Gas in einem Vertrag zum Zeitpunkt der Vertragserstellung ( contractObject.new) mit einem parametrisierten Konstrukteur schätze, gibt es eine falsche Schätzung der Gaskosten. ( web3.eth.estimateGasvon web3 api)

Was ich will
a) Wenn ich Gas mit einem Vertragskonstrukteur mit mehreren Parametern schätze, sollte es das richtige Gas schätzen. ( contractObject.newzum Aufrufen des Konstruktors)

b) Browser-Soldity gibt die richtige Gasschätzung des Vertrags mit parametrisiertem Konstruktor --> vor Vertragserstellung/-bereitstellung (wie Transaktionskosten oder Ausführungskosten, wie kann ich ihren Algorithmus mit Web3-API verwenden, um Gas korrekt zu schätzen?)

Wie benutzt du .estimateGas()? Mit .getData()?
Matthew Schmidt Ich verwende die Funktion "schätzenGas()" mit der Vertragsmethode, um Gas zu schätzen. Ich verwende keine .getData() Methode. zum Beispiel: - Methode contractInstance.myMethod.estimateGas ergibt das richtige Ergebnis. aber ich möchte contractInstance.new für den Konstruktoraufruf mit parametrisiert schätzen. Wenn ich estimateGas von contractInstance.new.estimateGas , gibt es den Fehler, dass diese Methode nicht existiert. wie man es repariert

Antworten (5)

Versuchen Sie es mit .getData().

.getData()gibt die verschlüsselten Parameter einer Funktion zurück, um die Transaktion manuell zu senden. Sie können dies dann einfügen web3.eth.estimateGas()(das auf web3.eth, nicht auf eine bestimmte Methode.), um das Senden der Transaktion zu simulieren.

Hier ist ein ungetestetes Beispiel, aber hoffentlich kann es Ihnen auf Ihrem Weg helfen:

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

Verweise:

web3.eth.estimateGas()

Ein Beispiel für die Verwendung von .getData() (Dies ist die vierte Option.)

Worauf bezieht sich „contractCode“ in Ihrer ersten Beispielzeile?
Hoppla! Hätte etwas klarer sein sollen. Das ist der Vertrags-Bytecode - was Sie davon bekommen, solc --binich werde meine Antwort bearbeiten.
Diese Methode scheint mit web3 Version 1.0 nicht zu funktionieren, da es kein getData()? Bearbeiten: Diese Frage gefunden, die besagt, dass sie encodeABI()anstelle von verwendet werden soll getData().

Beim Arbeiten mit web3.js Version 1.2.x gibt es keine .getData-Methode. Die Lösung, die ich gefunden habe, war die Gasschätzung der Methode .deploy(), die effektiv die Kosten der Vertragserstellung zurückgibt.

Die Reihenfolge der Operationen ist:

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

Mit web3js ist es ziemlich einfach. Zuerst müssen Sie Ihren Vertrag erstellen. Nach der Erstellung haben Sie contractABI und die Vertragsadresse wie folgt:

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'

Erstellen Sie mit diesen Informationen einfach den Vertrags-Proxy- ContractInstance und schätzen Sie ein TX auf eine Sign - Methode:

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

Der Proxy ist ein spezielles Objekt (verwenden Sie ein console.log, um alle Methoden anzuzeigen), um die Vertragsnutzung zu erleichtern. Wenn Sie eine Signiermethode haben , können Sie einen Tx zum Signieren erstellen:

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

wenn Sie wollen, um eine Funktion (ohne Transaktion) aufzurufen:

contractInstance.sign.call(param)
Die Frage bezieht sich auf die Gasschätzung bei der Kontakterstellung.

Web3 ermöglicht dies:

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

Versuchen Sie dies für die Bereitstellung neuer Verträge. Für mich geht das.