отправить вызов VS - различия и когда использовать, а когда не использовать

Может кто-нибудь объяснить разницу между использованием отправки и вызова для контрактов, а также когда использовать и не использовать эти разные методы?

Например :

   msg.sender.send(number);  
   msg.sender.call.value(number)();

Я знаю, что для отправки используется газ 2300, а для вызова не используется газ.

Ответы (3)

РЕДАКТИРОВАТЬ, декабрь 2019 г.: call.value()()теперь следует использовать для передачи эфира. (Не используйте функцию отправки или передачи.)

См.: Является ли transfer() безопасным после обновления Istanbul?

Спасибо за ответ, но я также искал дополнительную информацию о том, как эти разные методы работают на системном уровне. Например, генерирует ли метод call транзакции в блокчейне?
A .callне создает транзакцию; только что написал это, в котором есть другие детали, которые вы, возможно, ищете: ethereum.stackexchange.com/a/6477/42
Я думаю, что sendпосылает больше, чем 0 газа, не так ли? Отправляет 23000
sendотправляет 0 газа, но есть правило EVM, согласно которому получатель всегда получает стипендию в размере 2300 газа (так что, если он захочет, у него всегда будет достаточно газа, чтобы зарегистрировать, что он что-то получил).
Алекс Дарби, вероятно, путает .callJavascript (без транзакции) с .callSolidity (уже в транзакции).
Нет, я не путаю вызов из Javascript. В моем сообщении не упоминается Javascript,

1 Send() больше не подает газ. Он просто использует жестко закодированную стипендию (2300 газа), полученную из стоимости передачи стоимости (минимум 9040). Этого достаточно, чтобы отправить эфир, но также достаточно, чтобы выполнить одну дополнительную небольшую операцию регистрации (в резервной функции). Следующие операции будут потреблять больше газа, чем стипендия, предоставляемая резервной функции:

• Запись в хранилище

• Создание контракта

• Вызов внешней функции, потребляющей большое количество газа

• Отправка эфира

2 Если у send()вызова заканчивается газ, он не выдает ошибку, он просто возвращает false.

из Solidity Doc:

Если контракт получает эфир (без вызова функции), выполняется резервная функция. Контракт может полагаться только на «газовую стипендию» (2300 газа), доступную ему в то время. Этой стипендии недостаточно, чтобы каким-либо образом получить доступ к хранилищу. Чтобы убедиться, что ваш контракт может получать эфир таким образом, проверьте требования к газу для резервной функции (например, в разделе «Подробности» в браузере-солидности).

• Существует способ направить больше газа принимающему контракту с помощью addr.call.value(x)(). По сути, это то же самое, что и addr.send(x), только перенаправляет весь оставшийся газ и открывает получателю возможность выполнять более дорогостоящие действия. Это может включать обратный вызов контракта отправки или другие изменения состояния, о которых вы могли не знать. Таким образом, это обеспечивает большую гибкость как для честных пользователей, так и для злоумышленников.

Предупреждение : Контракты, которые получают эфир, но не определяют резервную функцию, вызывают исключение, отправляя эфир обратно (до версии Solidity v0.4.0 это было по-другому). Поэтому, если вы хотите, чтобы ваш контракт получал эфир, вы должны реализовать резервную функцию.

Хорошие моменты. Для ясности читателям фраза «не выдает ошибку, а просто возвращает false» также относится к .call(). И не могу не подчеркнуть, что .call()«обеспечивает большую гибкость как для честных пользователей, так и для злоумышленников».

address.transfer()

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

address.send()

  • возвращается falseв случае неудачи
  • направляет 2,300газовую стипендию, защищенную от повторного входа
  • следует использовать в редких случаях, когда вы хотите обработать сбой в контракте

address.call.value().gas()()

  • возвращается falseв случае неудачи
  • перенаправляет весь доступный газ, позволяет указать, сколько газа перенаправить
  • следует использовать, когда вам нужно контролировать, сколько газа пересылать при отправке эфира или вызывать функцию другого контракта

Вы можете прочитать более подробную информацию здесь https://ethereum.stackexchange.com/a/38642/18932