По сути, вам не нужно платить за вызов контракта, но если метод контракта выполняет много работы, вам нужно добавить газ в вызов контракта, чтобы предотвратить DoS-атаку следующим образом:
контракт.метод.вызов({газ: 1000000000})
Кто получает эту плату?
«Вызов» — это перегруженный термин, потому что это одна из форм вызова контракта (см. В чем разница между транзакцией и вызовом? ), и это зависит от того, где выполняется вызов по отношению к виртуальной машине Ethereum (EVM).
Вопрос contract.method.call({gas: 1000000000})
касается web3.js, который находится за пределами Solidity и EVM.
API web3.js называется web3.eth.call и используется для функций Solidityconstant
.
Никто не получает комиссию, потому что вызов «пробного запуска» является локальным для узла, к которому подключен web3.js: сеть и майнеры ничего не знают об этом вызове.
Однако, несмотря на то, что вызов является локальным, газ все еще «используется» , и все еще возможно исчерпать газ или (само) «DoS» при вызове постоянной функции Solidity. Например, как объясняется в разделе Могут ли постоянные функции Solidity быть произвольно сложными? , Geth "только" обеспечивает локальные вызовы с 50 миллионами газа:
if gas.Cmp(common.Big0) == 0 {
gas = big.NewInt(50000000)
}
Чтобы избежать «самостоятельного DoS», попробуйте больше газа, напримерcontract.method.call({gas: 999000000})
Более точная причина, по которой никто не получает комиссию , это то, что газ является счетчиком, а учет отличается от платы , выдержка:
В Биткойне измерение осуществляется с помощью байтов: количества байтов в транзакции. В Эфириуме вычисления также необходимо измерять, потому что небольшой объем кода может быть программой, которая будет работать вечно. Учет учета является одной из причин для газа. Но наличие газа не означает взимания платы.
Например, в приватной цепочке у каждой учетной записи может быть X газа в день, или у каждой учетной записи может быть Y газа за транзакцию, или какая-то другая схема. С другой стороны, наличие сборов не означает обязательного использования газа: сборы могут основываться на различных измерениях, например, на байтах. Безопасность в общедоступной цепочке блоков требует как газа, так и комиссий, в то время как альтернативы более применимы к частным цепочкам (например, схема, в которой каждая учетная запись имеет X газа в день, может быть атакована Сивиллой в общедоступной цепочке, где любой может создать учетную запись). .
Вызов контракта с помощью web3.eth.call по-прежнему измеряется, даже если за это не взимается плата, и поэтому газ по-прежнему задействован.
В Solidity call
это совершенно другой зверь, и это функция низкого уровня для контракта, позволяющая отправить другому контракту сообщение, как описано в разделе Что означает функция «вызова» в Solidity?
Следует отметить, когда .gas
используется, например:
contract.call.gas(1000)(bytes4(sha3("methodName()")))
это означает, что вызов подвызова methodName
будет ограничен 1000 газами: это не означает предоставление еще 1000 газов methodName
.
Если Solidity выполняется в контексте локального вызова «пробного запуска», комиссия за транзакцию никому не достается. Если Solidity выполняется в транзакции, комиссия всегда поступает майнеру блока, даже если есть ошибка Out of Gas или ошибка выполнения любого рода.
В случае успешного выполнения транзакции фактическая плата поступает майнеру, который решает блок. Чтобы избежать избыточности, я просто укажу здесь на некоторые детали: как транзакционные сборы Ethereum сравниваются с биткойнами? . Вывод здесь заключается в том, что комиссия в большинстве случаев не будет составлять 1000000000, но и не будет превышать ее.
В случае ошибки исполнения газ уничтожается навсегда, поэтому его никто не получает.
Также стоит упомянуть, что в случае «вызова» (в отличие от sendTransaction) выполнение будет локальным и не будет стоить газа, поэтому, в конце концов, у вызывающего абонента все еще будет газ, который был обещан. Использование «вызова» распространено для операций только для чтения, которые не изменяют состояние, потому что это быстрее и бесплатно.
Роб Хитченс
Сатоши Наканиши