как рассчитать стоимость газа?

У меня есть функция, которая перебирает массив, что может стоить много газа. Но я все еще хочу проверить примерную стоимость газа, а затем решить, должен ли я поддерживать проект или нет.

function giveAwayDividend(uint amount) onlyOwner payable {
for(uint i=0;i<size();i++){
    customerAddress[i].call.value((balances[customerAddress[i]] * amount * 100) / totalSupply)();
}}

Если я тестирую в тестовой сети, мне нужно вручную создать более 1000 учетных записей пользователей и отправить каждому из них какой-то токен, что кажется глупым. Есть ли лучший способ рассчитать стоимость газа? Например, если стоимость является линейной, я мог бы рассчитать стоимость для одного клиента, а затем умножить ее на количество клиентов. Вопрос в том, что я не думаю, что это линейно, может кто-нибудь пролить свет на это?

Ответы (2)

Использование Truffle и testrpc . На самом деле довольно легко создать среду разработки и протестировать различные варианты использования.

Для оценки газа он в основном основан на собственных функциях Web3:

  1. Вы можете получить цену на газ (в вэй), используяweb3.eth.getGasPrice

  2. Функция estimateGasдаст оценку газа для функции (с переданными параметрами)

  3. Умножьте количество газа на цену газа , чтобы получить оценку стоимости газа .

Например

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

Результат в моем случае (частная сеть):

> 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
Или web3.eth.gasPriceвместоweb3.eth.getGasPrice
Как мы делаем реальную сделку с газом?

Ответ, предоставленный Грегом Джинмартом, прекрасно объяснил, как оценить стоимость газа для функции. Здесь я хочу указать, что дизайн вашей функции giveAwayDividend()может быть уязвим для атак.

Поскольку каждый из циклов for платит эфир пользователю, и он выполняет следующий цикл только после того, как этот платеж будет успешно отправлен, это может быть случай, когда пользователь customerAddress[0]отказывается от платежа (они могут сделать это, имея контракт, запасной вариант которого функция преднамеренно терпит неудачу), тогда ваша функция giveAwayDividend()также будет каждый раз давать сбой и, таким образом, станет не вызываемой.

Лучшим подходом может быть то, что пользователи будут вызывать функцию remove(), чтобы средства поступали на их адрес только тогда, когда пользователи запрашивают это. Таким образом, злоумышленники могут сделать функцию недействительной только для своей учетной записи и не повлияют ни на кого другого.

Я также подумал о вашем решении, это технически идеальное решение, но ситуация такова: я хочу автоматически выплачивать дивиденды, чтобы моим пользователям не приходилось самим вызывать метод remove(), поскольку большинство из них являются инвесторами, которые не даже знаю что-нибудь о смарт-контракте.