Gas

Мы немного говорили о gas в предыдущих главах, а более подробно обсуждаем его в [gas]. Однако давайте рассмотрим некоторые основы роли компонентов gasPrice и gasLimit в транзакции.

Gas (газ) - это топливо для Ethereum. Gas не является ether - это отдельная виртуальный актив со своим собственным курсом по отношению к ether. Ethereum использует газ для контроля количества ресурсов, которые может использовать транзакция. Модель бесконечных вычислений требует определенной формы учета, чтобы избежать атак типа "отказ в обслуживании" или непреднамеренных транзакций, истощающих ресурсы.

Газ отделен от ether, чтобы защитить систему от волатильности, которая может возникнуть при быстрых изменениях стоимости ether, а также как способ управления важными и чувствительными соотношениями между стоимостью различных ресурсов, за которые платит газ (а именно, вычислений, памяти и хранения).

Поле gasPrice в транзакции позволяет создателю транзакции установить цену, которую он готов заплатить в обмен на газ. Цена измеряется в wei за единицу газа. В примере транзакции в [intro_chapter] ваш кошелек установил gasPrice равным 3 gwei (3 гигавея или 3 миллиарда wei).

Совет: Популярный сайт ETH Gas Station предоставляет информацию о текущих ценах на газ и другие актуальные метрики газа для основной сети Ethereum.

Кошельки могут регулировать цену gasPrice в транзакциях, которые они создают, чтобы добиться более быстрого подтверждения транзакций. Чем выше цена gasPrice, тем быстрее транзакция будет подтверждена. И наоборот, транзакции с более низким приоритетом могут иметь более низкую цену, что приведет к более медленному подтверждению. Минимальное значение, на которое можно установить gasPrice, равно нулю, что означает транзакцию без комиссии. В периоды низкого спроса на место в блоке такие транзакции вполне могут быть добыты.

Примечание: Минимально допустимая цена gasPrice равна нулю. Это означает, что кошельки могут генерировать совершенно бесплатные транзакции. В зависимости от мощности, они могут никогда не быть подтверждены, но в протоколе нет ничего, что запрещало бы бесплатные транзакции. Вы можете найти несколько примеров таких транзакций, успешно включенных в блокчейн Ethereum.

Интерфейс web3 предлагает предложение gasPrice, вычисляя медианную цену по нескольким кварталам (для этого можно использовать консоль truffle или любую консоль JavaScript web3):

> web3.eth.getGasPrice(console.log)
> null BigNumber { s: 1, e: 10, c: [ 10000000000 ] }

Второе важное поле, связанное с газом, - это gasLimit. Проще говоря, gasLimit - это максимальное количество единиц газа, которое создатель транзакции готов купить для завершения транзакции. Для простых платежей, то есть транзакций, которые переводят ether с одного EOA на другой EOA, необходимое количество газа установлено на уровне 21,000 единиц газа. Чтобы рассчитать, сколько ether это будет стоить, умножьте 21,000 на цену газа, которую вы готовы заплатить. Например:

> web3.eth.getGasPrice(function(err, res) {console.log(res*21000)} )
> 210000000000000

Если конечным адресом вашей сделки является контракт, то количество необходимого газа можно оценить, но нельзя определить с точностью. Это связано с тем, что контракт может оценивать различные условия, которые приводят к различным путям выполнения, с различными общими затратами на газ. Контракт может выполнить только простой расчет или более сложный, в зависимости от условий, которые находятся вне вашего контроля и не могут быть предсказаны.

Чтобы продемонстрировать это, давайте рассмотрим пример: мы можем написать умный контракт, который увеличивает счетчик при каждом вызове и выполняет определенный цикл количество раз, равное количеству вызовов. Возможно, на 100-м вызове он выдает специальный приз, как в лотерее, но для вычисления приза необходимо произвести дополнительные вычисления. Если вы вызовете контракт 99 раз, произойдет одно, но на 100-м вызове произойдет нечто совсем другое. Количество газа, которое вы заплатите за это, зависит от того, сколько других транзакций вызвали эту функцию до того, как ваша транзакция будет включена в блок. Возможно, ваша оценка основана на том, чтобы быть 99-й транзакцией, но прямо перед подтверждением вашей транзакции кто-то другой вызывает контракт в 99-й раз. Теперь вы - 100-я вызванная транзакция, и вычислительные усилия (и стоимость газа) намного выше.

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

Однако аналогия с топливным баком несколько обманчива. На самом деле это больше похоже на кредитный счет на заправке компании, где вы платите после завершения поездки, исходя из того, сколько бензина вы фактически использовали. Когда вы передаете транзакцию, одним из первых шагов проверки является проверка того, что на счете, с которого она была произведена, достаточно ether для оплаты gasPrice * gasLimit. Но сумма фактически не списывается с вашего счета до завершения транзакции. Счет выставляется только за газ, фактически потребленный вашей транзакцией, но перед отправкой транзакции у вас должен быть достаточный баланс для максимальной суммы, которую вы готовы заплатить.