Недостаточно газа при вызове метода контракта - Browser Solidity & Metamask

Пытаясь вызвать метод sendFundsToFriend() в контракте тестовой сети https://testnet.etherscan.io/address/0xce8efd03766a309af57ddeb9c79f3e7cd23da0df (код контракта на https://gist.github.com/anonymous/5bdc3d9032a8b3cb5cba7c7625afa4d7 ), я получил:

Warning! Error encountered during contract execution [Out of gas]

Результат TX говорит:

Result: {
  "blockHash": "0x585ca866c5143090c7a82443269d55658a176a018b1ad90827ec70adc1ff66c8",
  "blockNumber": 465927,
  "contractAddress": null,
  "cumulativeGasUsed": 508930,
  "from": "0xe5f68950d479fab12797dabbe5a4b0d88ec7a722",
  "gasUsed": 58787,
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "root": "0x1289d7517d81fa8c4894c0cd97fd200ec4e9f0fecebba586435daca8e4e8f9ec",
  "to": "0xce8efd03766a309af57ddeb9c79f3e7cd23da0df",
  "transactionHash": "0x703d7657c093557d1cd42dfeb7b8d0d3b74e413d22e8009b26d7ac966c85d048",
  "transactionIndex": 3
}
Transaction cost: 58787 gas.

введите описание изображения здесь

При отправке tx лимит газа транзакции устанавливается равным 3000000, что является значением надежности браузера по умолчанию.

Если стоимость транзакций составляет 58787 газа, а лимит составляет 3000000, почему возникает ошибка об отсутствии газа? Есть идеи? Спасибо!

PS: попробовал аналогичный tx с ноды geth вместо использования metamask+browser-solidity, и это сработало нормально:

https://testnet.etherscan.io/tx/0x56465b6594769578d9223ca902757780600dd2628074aedcf9635fb590b75bfa

Итак, я делаю что-то не так с надежностью браузера при вызове метода контракта, или это может быть какая-то ошибка в этой среде...

Это cumulateGasUsed нужно проверить, 508930
Согласно ethereum.stackexchange.com/questions/3346/… Cumulative Gas относится ко всем транзакциям в одном блоке. Почему я должен платить комиссию за все транзакции в блоке?
Кроме того, 3000000 больше, чем 508930
Метод sendFundsToFriend действительно не подлежит оплате. Это договор, который отправляет собственные средства другу, а не отправителю. Сумма должна быть 0.
@JuanIgnacioPérezSacristán: извините, вы были правы, все транзакции суммируются.
Трудно вам помочь, если мы не видим код контракта. Не могли бы вы опубликовать соответствующую плотность?
Спасибо. Код контракта на gist.github.com/anonymous/5bdc3d9032a8b3cb5cba7c7625afa4d7.

Ответы (3)

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

Способ проверить это — использовать metamask+browser-solidity для отправки на адрес, на котором уже есть ETH. Если это не удается, то это не так. Если это не сбой, то, вероятно, это то, что произошло.

Это все еще может быть ошибка в метамаске, так как она неправильно рассчитала, сколько газа нужно предоставить.

РЕДАКТИРОВАТЬ:

Возможно, я нашел ответ.

Сравнение успешного geth с неудачной метамаской (я полагаю) показывает, что необработанные транзакции на самом деле разные. Я подозреваю, что клиент, отправивший неудачную транзакцию, форматирует поля по-разному или просто с ошибками.

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

К сожалению, это тоже не работает: testnet.etherscan.io/tx/… В этом случае адресом назначения является testnet.etherscan.io/address/… с несколькими предыдущими транзакциями и ненулевым балансом. Этот же tx с использованием узла geth работает нормально с узла geth => testnet.etherscan.io/tx/…
При внимательном рассмотрении кажется, что метамаск посылает ровно столько газа, а геты посылает больше газа. Я не уверен, почему он сломается, если его достаточно - есть небольшое количество неясных возможностей. (Я не думаю, что это проблема возврата, поскольку нет удаления хранилища или самоуничтожения.)
газ, отправленный по метамаске: 33787 на testnet.etherscan.io/tx/… 58787 на testnet.etherscan.io/tx/… и testnet.etherscan.io/tx/… в то время как geth отправляет 1000000, но тратит всего 23263 => testnet. etherscan.io/tx/…
Я до сих пор не могу думать ни о чем, кроме как о нехватке газа, поскольку в остальном транзакции идентичны. Какой клиент его отправил, не имеет значения, так как его исполняют майнеры.
Или нет!? Смотрите мое последнее редактирование.
Спасибо, Мэтью. Баг с метамаской тоже моя гипотеза.

Сначала я подумал, что, может быть, мы каким-то образом неправильно рассчитываем газ и теряем транзакции, поскольку большинство неудачных транзакций имеют очень низкий газ, но на самом деле иногда казалось, что почти идентичные транзакции успешны с меньшим газом, как эта пара: https://testnet. etherscan.io/tx/0x5dde4e0536756b380b34a6fed79bda50bbe274c25b07ac1812f0d816917b9fbd https://testnet.etherscan.io/tx/0xd2f0047ee8d6ed27a8435352c809a9326edd09e9c32c0d

Я заметил одну вещь: эти два контракта на самом деле разные, поэтому я не уверен, исходный код какого из них вы разместили.

Также стоит отметить, что вы используете несколько шаблонов для отправки, которые не рекомендуются в документации Solidity: https://solidity.readthedocs.io/en/develop/security-considerations.html?highlight=send#sending-and . -приемный-эфир

Я заметил, что некоторые из неудачных транзакций относятся к контрактам, и это один из наиболее опасных моментов для использования sendфункции, поскольку эти контракты могут сжечь газ.

Извините, потратил некоторое время на это, не уверен, что нашел его.

Моя вина. Есть две версии контракта, но последняя — это testnet.etherscan.io/address/…, и именно она соответствует исходному коду.
Итак, должен ли я использовать шаблон вывода вместо шаблона отправки?
Вероятно, вам следует использовать изъятие вместо отправки, но это не совсем объясняет, почему это произошло.

Я столкнулся с той же проблемой с Remix + Ganache, я переключился на другую тестовую сеть Ethereum, и проблема не появилась. Попробуйте с какой-нибудь другой тестовой сетью.