Ich habe eine Funktion, die ein Array durchläuft, was viel Benzin kosten könnte. Aber ich möchte trotzdem die geschätzten Benzinkosten testen und dann entscheiden, ob ich das Design beibehalten soll oder nicht.
function giveAwayDividend(uint amount) onlyOwner payable {
for(uint i=0;i<size();i++){
customerAddress[i].call.value((balances[customerAddress[i]] * amount * 100) / totalSupply)();
}}
Wenn ich auf Testnet teste, muss ich manuell über 1.000 Benutzerkonten erstellen und jedem von ihnen ein Token schicken, was dumm erscheint. Gibt es eine bessere Möglichkeit, die Gaskosten zu berechnen? Wenn die Kosten beispielsweise linear sind, könnte ich die Kosten für einen Kunden berechnen und dann mit der Anzahl der Kunden multiplizieren. Die Frage ist, ich glaube nicht, dass es linear ist. Kann jemand etwas Licht ins Dunkel bringen?
Mit Truffle und testrpc . Es ist eigentlich ziemlich einfach, eine Entwicklungsumgebung zu erstellen und verschiedene Anwendungsfälle zu testen.
Für die Gasschätzung basiert es hauptsächlich auf nativen Web3-Funktionen:
Sie können den Gaspreis (in wei) mit abrufenweb3.eth.getGasPrice
Die Funktion estimateGas
gibt die Gasschätzung für eine Funktion (mit den übergebenen Parametern)
Multiplizieren Sie die Anzahl der Gase mit dem Gaspreis , um die Schätzung der Gaskosten zu erhalten .
Zum Beispiel
var TestContract = artifacts.require("./Test.sol");
// Run unit tests to populate my contract
// ...
// ...
// getGasPrice returns the gas price on the current network
TestContract.web3.eth.getGasPrice(function(error, result){
var gasPrice = Number(result);
console.log("Gas Price is " + gasPrice + " wei"); // "10000000000000"
// Get Contract instance
TestContract.deployed().then(function(instance) {
// Use the keyword 'estimateGas' after the function name to get the gas estimation for this particular function
return instance.giveAwayDividend.estimateGas(1);
}).then(function(result) {
var gas = Number(result);
console.log("gas estimation = " + gas + " units");
console.log("gas cost estimation = " + (gas * gasPrice) + " wei");
console.log("gas cost estimation = " + TestContract.web3.fromWei((gas * gasPrice), 'ether') + " ether");
});
});
Ergebnis in meinem Fall (privates Netzwerk):
> truffle test
Using network 'test'.
Compiling .\contracts\Migrations.sol...
Compiling .\contracts\Test.sol...
Gas Price is 20000000000 wei
gas estimation = 26794 units
gas cost estimation = 535880000000000 wei
gas cost estimation = 0.00053588 ether
Die Antwort von Greg Jeanmart erklärte perfekt, wie man die Gaskosten für eine Funktion schätzt. An dieser Stelle möchte ich darauf hinweisen, dass das Design Ihrer Funktion giveAwayDividend()
möglicherweise anfällig für Angriffe ist.
Da jede for-Schleife Ether an einen Benutzer zahlt und die nächste Schleife erst ausführt, nachdem diese Zahlung erfolgreich gesendet wurde, könnte es der Fall sein, dass der Benutzer customerAddress[0]
die Zahlung verweigert (sie können dies tun, indem sie einen Vertrag haben, dessen Fallback Funktion absichtlich fehlschlägt), dann giveAwayDividend()
würde Ihre Funktion dann auch jedes Mal fehlschlagen und somit unaufrufbar werden.
Ein besserer Ansatz könnte darin bestehen, dass Benutzer eine Funktion „draw()“ aufrufen, sodass das Guthaben nur dann an ihre Adresse geht, wenn die Benutzer dies anfordern. Auf diese Weise können Angreifer die Funktion nur für ihr Konto ungültig machen und andere nicht beeinträchtigen.
José Alban
web3.eth.gasPrice
stattweb3.eth.getGasPrice
Schamon