Wie kann ich den Gaspreis festlegen, während ich einen Vertrag mit web3.js bereitstelle?

Ich habe kürzlich einen Geth-Knoten im Rinkeby-Netzwerk eingerichtet. Und während ich gewöhnliche Transaktionen problemlos in Sekunden senden kann, kann ich eine Vertragserstellung anscheinend nicht in weniger als einer Stunde durchführen. Wenn ich einen einfachen Vertrag in Remix kompiliere und dann den von ihm generierten web3.js-Bereitstellungscode in die Geth-Konsole einfüge, wird die Transaktion an das Netzwerk gesendet, aber dann sitzt sie einfach über eine Stunde lang dort, ohne dass jemals einer der autorisierten Knoten vorhanden ist es in einen Block aufnehmen. Obwohl es schließlich akzeptiert wird.

Ich frage mich, ob das Problem hier der Benzinpreis sein könnte. Basierend auf Etherscan sieht es so aus, als hätte web3.js beschlossen, den Gaspreis für die Transaktion auf 4 Gwei festzulegen. Ich habe überprüft, dass der Durchschnitt für das Netzwerk derzeit nur 2 Gwei beträgt, aber dennoch möchte ich dies als Möglichkeit ausschließen. (Das Gaslimit ist definitiv kein Problem - auf 4700000 eingestellt und das geschätzte Gas für den Vertragserstellungscode laut Remix ist nur 80924.)

Wenn jemand dies liest und vermutet, dass das, was ich sehe, auf etwas anderes als den zu niedrigen Benzinpreis zurückzuführen ist, können Sie sich die Transaktion hier ansehen und Vorschläge machen:

https://rinkeby.etherscan.io/tx/0xe134c193cead33031e3348ebb1db42115fdf156cb5e1a1d43d5c4ecfdf026413

Wie auch immer, meine spezielle Frage ist: Woher kommt dieser Standard-Gaspreis von 4 gwei, und wie kann ich ihn mit etwas Höherem überschreiben?

Aus irgendeinem Grund wird in der Dokumentation für web3.js keine Möglichkeit erwähnt, den Gaspreis für eine Vertragserstellung anzugeben, obwohl es eine Möglichkeit bietet, ihn für eine gewöhnliche Transaktion anzugeben:

https://github.com/ethereum/wiki/wiki/JavaScript-API

Kann ich einfach eine zusätzliche Option an web3.eth.contract() von gasPrice= oder vielleicht an myContract.new() übergeben?

Die Transaktion, mit der Sie verknüpft sind, scheint vor über einer Stunde erfolgreich gewesen zu sein.
Ja, tut mir leid, ich dachte, mein Browser sollte sich automatisch aktualisieren, aber anscheinend war das aus irgendeinem Grund nicht der Fall. Wie auch immer, es hat über eine Stunde gedauert, bis es fertig war, was immer noch viel zu lang ist – ich habe es jetzt bearbeitet, um das widerzuspiegeln.
Ich bin mir nicht sicher, aber die Verzögerung könnte auf das sehr hohe Gaslimit zurückzuführen sein. Blöcke haben ein Gaslimit, und daher ist es schwieriger, sehr umfangreiche Transaktionen in einen Block zu packen. (Ihre Transaktion hat eigentlich nicht so viel Gas verbraucht, aber ein Miner, der einen Block vorbereitet, weiß das vermutlich nicht, bis er versucht, Ihre Transaktion einzubeziehen.) Versuchen Sie beim nächsten Mal, ein niedrigeres Gaslimit anzugeben.
Oh wow! Mir war nicht klar, dass das einen Unterschied machen könnte. Eine seltsame Sache, die mir jetzt auffällt, ist, dass das geschätzte Gas durch Remix nur 80924 war. Aber das tatsächlich verbrauchte Gas war 908733. Auch wenn es immer noch nicht so viel ist, ist es viel mehr als erwartet und ich bin mir nicht sicher warum. Es sieht so aus, als ob die Transaktion über eine Stunde lang anhängig war, aber in weniger als 15 Sekunden abgebaut wurde, nachdem sie schließlich akzeptiert wurde.
Welches genaue Feld haben Sie in Remix mit 80924 gesehen? Die "Transaktionskosten" sind die, die Sie wollen. Natürlich können die Kosten zwischen den Netzwerken variieren, je nachdem, was die Transaktion bewirkt. ZB könnte es proportional zur Blocknummer oder einem Wert in einem anderen Vertrag usw. funktionieren. Sie müssten Ihren Code teilen, damit jemand über so etwas spekulieren kann.
Ebenfalls seltsam - die Gasgrenze von 4700000 wurde automatisch durch Remix in derselben Kompilierung generiert wie die Gasschätzung von 80924. Keine Ahnung, warum sie es so viel höher eingestellt haben, ich habe einfach den Bereitstellungscode kopiert, ohne es zu bemerken.
Habe es von "totalCost" in GASESTIMATES: "Creation": { "codeDepositCost": "80800", "executionCost": "124", "totalCost": "80924" }
Ah, in den "Details" auf der Registerkarte "Kompilieren"? Ich sehe dort auch 4700000 für jeden Code. Ich denke, es ist nur fest codiert. Für die „GASESTIMATES“ habe ich keine Erklärung. Ich müsste den Code sehen.

Antworten (3)

Aus der Dokumentation:

var contractInstance = MyContract.new([constructorParam1] [, constructorParam2],
  {data: '0x12345...', from: myAccount, gas: 1000000});

Ja, Sie können diesem Objekt einfach ein hinzufügen gasPrice:

var contractInstance = MyContract.new([constructorParam1] [, constructorParam2],
 {data: '0x12345...', from: myAccount, gas: 1000000, gasPrice: web3.toWei(2, 'gwei')});
Vielen Dank. Wissen Sie, ob es irgendwo eine Dokumentation für web3.js gibt, die alle Parameter auflistet, die jede Methode akzeptieren kann? Vielleicht ist es besser, im Zweifelsfall einfach in den Quellcode zu schauen?
Ich sehe überhaupt keine Dokumentation für .new(), aber ich bin mir ziemlich sicher, dass der Parameter genau derselbe ist wie in sendTransactionund dergleichen: github.com/ethereum/wiki/wiki/… .

web3 hat auch eine Funktion, um das benötigte Gas abzuschätzen, Sie könnten so etwas tun:

var gasEstimate = web3.eth.estimateGas({data: bytecode});
var contract = web3.eth.contract(abi);
var instance = contract.new({data: bytecode, from: from, gas: gasEstimate});
var receipt = web3.eth.getTransactionReceipt(instance.transactionHash);

Sie können den Gaspreis in Ihrem Code wie unten überschreiben.

    const tx = {
      from: walletAddress,
      to: contractAddress,
      gas: 4700000,
      gasPrice: 20000000000,
      data: encodedABI,
    };

Wo Sie die tx-Variable wie unten verwenden können (ich habe den Teil übersprungen, in dem Sie Ihren HttpProvider instanziieren müssen)

....
...
smartContract = new web3.eth.Contract(abi, contractAddress);

const privateKey = '0x' + '12714D.....A3D8CC53';
const walletAddress = '0x77.....60';

// change this to whatever contract method you are trying to call, e.g. buyToken(type, title, desc)
const query = smartContract.methods.buyToken(type, title, desc);
const encodedABI = query.encodeABI();
const tx = {
  from: walletAddress,
  to: contractAddress,
  gas: 4700000,
  gasPrice: 10,
  data: encodedABI,
};

const account = web3.eth.accounts.privateKeyToAccount(privateKey);
console.log(account);
web3.eth.getBalance(walletAddress).then(console.log);

web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
  const tran = web3.eth
    .sendSignedTransaction(signed.rawTransaction)
    .on('confirmation', (confirmationNumber, receipt) => {
      console.log('=> confirmation: ' + confirmationNumber);
    })
    .on('transactionHash', hash => {
      console.log('=> hash');
      console.log(hash);

    })
    .on('receipt', receipt => {
      console.log('=> reciept');
      console.log(receipt);
    })
    .on('error', console.error);
});

Ihre Transaktionsgebühr wäre verbrauchtes Gas x Gaspreis. Woher weiß man, dass Gas verwendet wird? Sie können dies nur wissen, nachdem es verwendet wurde, z. B. durch Anzeigen Ihres Transaktionsbelegs, siehe Abbildung unten (unter dem Transaktionskostenelement in Remix, wo 206993 Gas angezeigt wird).

Geben Sie hier die Bildbeschreibung ein

P/S: ICH BIN NOCH EIN NEUER BEI ETHEREUM UND MÖCHTE NUR HELFEN. WENN ICH IRGENDEINEN FEHLER GEMACHT HABE, BITTE NICHT DOWNVOTEN, SONDERN KOMMENTARE LASSEN UND ICH WERDE MEINE ANTWORT BEARBEITEN