Бросок против возвращения

Мы пытаемся выяснить, следует ли использовать return или throw в Solidity, когда условие терпит неудачу, и мы не предполагаем вредоносность пользователя. Вот плюсы и минусы, которые мы догадались до сих пор:

Зачем использовать throw

  • Любые побочные эффекты кода возвращаются
  • Некоторые кошельки могут заранее предсказать throw, предупредив пользователя

Зачем использовать return

  • Меньше газа потребляется ничего не подозревающим пользователем (опять же, предполагая не злонамеренный вызов).
  • Вызывающий контракт может изящно восстанавливаться после отказа, в отличие от throw.

Есть ли какие-либо другие соображения (или лучшие практики), о которых мы должны знать?

18 голосов | спросил ronme 16 32016vEurope/Moscow11bEurope/MoscowWed, 16 Nov 2016 04:13:47 +0300 2016, 04:13:47

2 ответа


9

Все соображения в вопросе полезны.

throw безопаснее, поскольку он гарантирует отсутствие побочных эффектов, но еще одно соображение - отчет об ошибках. С throw в настоящее время не имеет возможности получить дополнительную информацию об ошибке , тогда как коды событий и ошибок могут использоваться с return, чтобы передать более подробную информацию об ошибке .

Еще одна вещь, о которой нужно знать при использовании web3.js, заключается в том, что когда возникает Solidity throw, в настоящее время У web3.js есть проблема с false значениями .

EDIT: Поскольку throw потребляет весь газ, следите за Инструкция EIP 140 REVERT :

  

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

ответил eth 16 32016vEurope/Moscow11bEurope/MoscowWed, 16 Nov 2016 04:49:31 +0300 2016, 04:49:31
3

Вы также можете подумать, почему not использовать throw /return:

Почему бы не использовать throw

  • Весь газ потребляется, все возвращается
  • Невозможно сообщить вызывающим абонентам, почему сбой вызова
  • Ошибки не могут быть пойманы, поэтому их нельзя обработать изящно

Почему бы не использовать return

  • Для абонентов может быть непонятно, что функция может безуспешно работать. Это может привести к катастрофическим последствиям: contract.doSomeImportantCall() может возвращать false, но вызывающий вместо этого ожидал броска, поэтому, если они не проверили возвращаемое значение, могут произойти плохие вещи.
  • Вы обнаружите, что возвращаете сразу несколько значений: например, returns (bool _successful, uint _result) vs returns (uint _result)
  • Обработка нескольких возвращаемых значений является громоздкой и труднее протестировать.

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

ответил Ether Dude 18 J0000006Europe/Moscow 2017, 03:00:31

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132