原文地址: https://ethereum.stackexchange.com/questions/19341/address-send-vs-address-transfer-best-practice-usage

address.transfer()

  • throws on failure
  • forwards 2,300 gas stipend (not adjustable), safe against reentrancy
  • should be used in most cases as it's the safest way to send ether

address.send()

  • returns false on failure
  • forwards 2,300 gas stipend (not adjustable), safe against reentrancy
  • should be used in rare cases when you want to handle failure in the contract

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

  • returns false on failure
  • forwards all available gas (adjustable), not safe against reentrancy
  • should be used when you need to control how much gas to forward when sending ether or to call a function of another contract

Detailed version below:

The relative tradeoffs between the use of someAddress.send()someAddress.transfer(), and someAddress.call.value()():

  • someAddress.send()and someAddress.transfer() are considered safe against reentrancy. While these methods still trigger code execution, the called contract is only given a stipend of 2,300 gas which is currently only enough to log an event.
  • x.transfer(y) is equivalent to require(x.send(y)), it will automatically revert if the send fails.
  • someAddress.call.value(y)() will send the provided ether and trigger code execution. The executed code is given all available gas for execution making this type of value transfer unsafe against reentrancy.

Using send() or transfer() will prevent reentrancy but it does so at the cost of being incompatible with any contract whose fallback function requires more than 2,300 gas. It is also possible to use someAddress.call.value(ethAmount).gas(gasAmount)() to forward a custom amount of gas.

One pattern that attempts to balance this trade-off is to implement both a push and pull mechanism, using send() or transfer() for the push component and call.value()() for the pull component.

It is worth pointing out that exclusive use of send() or transfer() for value transfers does not itself make a contract safe against reentrancy but only makes those specific value transfers safe against reentrancy.

More details are here https://consensys.github.io/smart-contract-best-practices/recommendations/#be-aware-of-the-tradeoffs-between-send-transfer-and-callvalue

Reasons for adding transfer()https://github.com/ethereum/solidity/issues/610


call() can also be used to issue a low-level CALL opcode to make a message call to another contract:

if (!contractAddress.call(bytes4(keccak256("someFunc(bool, uint256)")), true, 3)) {
revert;
}

The forwarded value and gas can be customized:

contractAddress.call.gas(5000)
.value(1000)(bytes4(keccak256("someFunc(bool, uint256)")), true, 3);

This is equivalent to using a function call on a contract:

SomeContract(contractAddress).someFunc.gas(5000)
.value(1000)(true, 3);

Beware of the right padding of the input data in call()https://github.com/ethereum/solidity/issues/2884


transfer()send() and call() functions are translated by the Solidity compiler into the CALLopcode.

As explained on the Subtleties page in Ethereum's wiki:

CALL has a multi-part gas cost:

  • 700 base
  • 9000 additional if the value is nonzero
  • 25000 additional if the destination account does not yet exist (note: there is a difference between zero-balance and nonexistent!)

最新文章

  1. Windows Programming ---- Beginning Visual C#
  2. 夺命雷公狗-----React---23--小案例之react经典案例todos(完成添加任务)
  3. ImFire即时通讯系统构建(需求)
  4. iOS 中self和super如何理解?
  5. SQL语句 远程操作数据库
  6. Android的TextView使用Html来处理图片显示、字体样式、超链接等
  7. Oracle控制文件操作
  8. 抓包工具Fidder详解(主要来抓取Android中app的请求)
  9. VSFTPD 源码安装升级
  10. MYSQL数据库学习五 表的操作和约束
  11. 201621123050 《Java程序设计》第11周学习总结
  12. 整合 ucenter 注册自动激活
  13. Vue-移动端项目真机测试
  14. 第三方jar包导入unity
  15. 【译】第五篇 SQL Server安全架构和安全
  16. Python-GIL 进程池 线程池
  17. netty]--最通用TCP黏包解决方案
  18. js的面向对象
  19. codevs1001 舒适的路线 - 贪心 - 并查集
  20. struts全包导入问题

热门文章

  1. 使用Audition录制自己的歌曲
  2. ActionContextCleanUp作用
  3. MATLAB的一些应用--最近用的比较多
  4. Kernel,Shell,Bash 的关系
  5. 调试VBA程序常用方法
  6. 笔记:LIR2032 电池充电记录
  7. 主窗体上按钮jig画图时,CAD得不到焦点的问题
  8. dubbox部署到jdk1.7环境,启动:java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()
  9. css中伪类和伪元素的区别
  10. 关于yii2 REST api 的问题