Ich versuche, web3 zu verwenden, um den gesamten (oder so viel wie möglich) Saldo eines Kontos auf ein anderes Konto zu übertragen. Hier ist der Code, den ich bisher habe:
var sender = web3.eth.accounts[0];
var receiver = web3.eth.accounts[1];
var totalBalance = web3.eth.getBalance(sender);
var valueToSend = totalBalance;
transactionObject = {
from: sender,
to: receiver,
value: valueToSend
}
web3.eth.sendTransaction(transactionObject);
Ich weiß jedoch, dass der vorherige Code das folgende Problem hat:
Ich habe in einem anderen Beitrag folgende Empfehlung gesehen:
subtrahiere die totalBalance von gas*price , also:
valueToSend = totalBalance - (gas*price);
FRAGE / PROBLEM:
aber das Problem, das ich hier habe, ist, wie würde das im Code aussehen? Ich weiß nicht, wie ich den aktuellen price
Code erhalten kann. Und für das Gas verstehe ich, dass es unterschiedliche Werte für Gas gibt, je nachdem, wie schnell eine Transaktion ablaufen soll, aber gibt es einen web3
Code, der das Mindeste und Höchste definiert, das Sie verwenden können? Oder gibt es irgendwo ein Diagramm, das es online definiert? Und wie würde das im Code aussehen?
Wenn Sie an eine Adresse senden, die keine Vertragsadresse ist, beträgt das Gas immer 21000.
Für einen Vertrag können Sie mit abschätzen web3.eth.estimateGas
. Es berechnet das Gas, das den Vertrag lokal ausführt. Wenn die Transaktion also abgebaut wird, kann das Ergebnis anders sein. Normalerweise fügen Sie ein Extra hinzu, um sicherzustellen, dass es funktioniert.
Aber ich denke, Ethereum-Entwickler sind sich des Problems bewusst, ein Konto mit zu wenig Ether zu verlassen, um eine neue Überweisung zu tätigen, es gab Diskussionen, wer für das Gas bezahlen kann.
Um den zu verwendenden Gaspreis zu ermitteln, können Sie versuchen web3.eth.gasPrice
, aus der Dokumentation
Diese Eigenschaft ist schreibgeschützt und gibt den aktuellen Gaspreis zurück. Der Gaspreis wird durch den mittleren Gaspreis der x letzten Blöcke bestimmt.
Wie der Wert ermittelt wird, ist nicht dokumentiert. Für eine detailliertere Analyse können Sie ethgasstation.info überprüfen, die Website scheint keine API bereitzustellen.
Sie können das Gas schätzen, indem Sie verwenden web3.eth.estimateGas
, um eine Schätzung des Gasverbrauchs Ihrer Transaktionen zu erhalten, und dann können Sie das geschätzte Gas von der Gesamtbilanz abziehen, um Sie zu erhalten valueTosend
.
transactionObject = {
from: sender,
to: receiver,
value: totalBalance
}
var estimatedGas = web3.eth.estimateGas(transactionObject);
web3.eth.getGasPrice(function(error, result){
gasPrice = result.toNumber();
var gasValue = estimatedGas * gasPrice
var valueToSend = totalBalance - gasValue;
});
Außerdem können Sie, um nur zu erwähnen, gasPrice Ihrer Wahl angeben, indem Sie gasPrice
in config verwenden. Es ist jedoch besser, wenn Sie das Standardgas nicht ändern. Auch wenn Sie eth
an EOA senden, ist Gas immer 21000, Sie können also schätztesGas durch const 21000 ersetzen.
Diese Lösung dient dazu, das gesamte Guthaben eines Kontos auf ein anderes reguläres Konto (kein Vertragskonto) zu senden, auf dem das Gas immer 21.000 beträgt.
Der wichtige Teil der folgenden Antwort ist die Verwendung von BigNumber-Mathematik, oder Sie werden manchmal mit falschen Zahlen enden und Ihre Transaktion wird abgelehnt, oder Sie werden etwas Restgas auf Ihrem Ursprungskonto zurücklassen.
var from = {from account};
var to = {to account};
var balance = eth.getBalance(from);
var gas = new BigNumber(21000);
// You can use gasPrice=web3.eth.gasPrice or look up http://ethgasstation.info/
var gasPrice = web3.utils.toWei(1, "gwei");
var cost = gas.mul(gasPrice);
var sendAmount = balance.sub(cost);
var tx = eth.sendTransaction({from: from, to: to, gas: gas, gasPrice: gasPrice, value: sendAmount});
eth.getTransaction(tx);
Wenn Sie versuchen, das gesamte Guthaben von einem Konto auf ein Vertragskonto zu überweisen, wird das Problem viel schwieriger, da das geschätzte Gas (mit web3.eth.estimateGas(...)
) selten dem tatsächlich verbrauchten Gas entspricht.
Und ein Beispiel für einige falsche Berechnungen, wenn BigNumber-Mathematik nicht verwendet wird:
// eth.getBalance(...) returns BigNumber. Number simulated in this case
> balance=new BigNumber(49999979000000000000);
49999979000000000000
> balance
49999979000000000000
> gas=21000
21000
> gasPrice=web3.toWei(1, "gwei");
"1000000000"
> cost=gas*gasPrice;
21000000000000
> cost
21000000000000
> incorrectSendAmount=balance-cost
49999958000000010000
> balance-incorrectSendAmount
20999999995904
// Small error in the calculations
> balance-incorrectSendAmount-cost
-4096
Und die gleichen Berechnungen bei der Verwendung von BigNumber-Mathematik:
// eth.getBalance(...) returns BigNumber. Number simulated in this case
> balance=new BigNumber(49999979000000000000);
49999979000000000000
> balance
49999979000000000000
> gas=new BigNumber(21000)
21000
> cost=gas.mul(gasPrice);
21000000000000
> correctSendAmount=balance.sub(cost);
49999958000000000000
// No errors in the calculations
> balance.sub(correctSendAmount).sub(cost)
0
Jonathan