Solidity transfer vs send 区别
原文地址: https://ethereum.stackexchange.com/questions/19341/address-send-vs-address-transfer-best-practice-usage
- 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
- 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
- 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()
andsomeAddress.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 torequire(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 CALL
opcode.
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!)
Solidity transfer vs send 区别的更多相关文章
- read、write 与recv、send区别 gethostname
recv相对于read有什么区别呢? 其实它跟read函数功能一样,都可以从套接口缓冲区sockfd中取数据到buf,但是recv仅仅只能够用于套接口IO,并不能用于文件IO以及其它的IO,而read ...
- 页面跳转Transfer与Redirect的区别你知道吗?
一 前言 关于页面跳转的方式常用的应该就是,链接跳转,js跳转,Server.Tranfser和Response.Redirect 这几种,可是在Tranfser与Redirect之间用哪种更好(本文 ...
- Response.Redirect()、Server.Execute和Server.Transfer的区别
1.Response.Redirect(): Response.Redirect方法导致浏览器链接到一个指定的URL. 当Response.Redirect()方法被调用时,它会创建一个应答,应答头中 ...
- 【转】页面跳转Transfer与Redirect的区别你知道吗?
一 前言 关于页面跳转的方式常用的应该就是,链接跳转,js跳转,Server.Tranfser和Response.Redirect 这几种,可是在Tranfser与Redirect之间用哪种更好(本文 ...
- 页面跳转 Server.Transfer和 Response.Redirect的区别
1.Server.Transfer 用于把处理的控制权从一个页面转移到另一个页面,在转移的工程中没有离开服务器内部控件(如request,session等)保存的信息不变.因此你能从a页面跳转到b页面 ...
- Solidity
起因是Xenc师傅给我截了张图,我日 居然看不懂 ,一搜才知道,之前学的版本有些老了.. 这次学下新一点的记录下 HelloWorld pragma solidity ^0.6.0; // versi ...
- Solidity的三种转账方式与比较
转账的3种方式 123 address.transfer()address.send()address.call.value().gas()() 转账transfer 12345678910 func ...
- java并发:阻塞队列
第一节 阻塞队列 1.1 初识阻塞队列 队列以一种先进先出的方式管理数据,阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作是:在队列为空时,获取元素的线程会等待队列 ...
- 10分钟 5步 发布以太坊 ERC20 代币
1.安装 METAMASK Brings Ethereum to your browser 一个可以浏览器上进行操作的以太坊钱包,推荐 Chrome. Chrome 插件安装地址: https://c ...
随机推荐
- C++中cin的使用总结
在学习C++时大家肯定迷惑过关于输入输出各种输出函数的功能,现在来总结一下各种函数的简单用法. cin建有一个缓冲区,即输入缓冲区.一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲 ...
- Webpack-dashboard 简单使用
1. 安装 npm install webpack-dashboard --save-dev 2. 配置说明 webpack config // Import the plugin: var Dash ...
- OpenWRT mt7620n 系统升级引起的问题
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/qianguozheng/article/details/27237175 OpenWRT系统升级採用 ...
- 微软发布WCF教程及大量示例
继前面 微软公司发布Windows Communication Foundation (WCF)和Windows CardSpace的示例程序之后,微软今天又发布了WF的教程和大量示例,对于学习WF的 ...
- UOJ #188 Sanrd —— min_25筛
题目:http://uoj.ac/problem/188 参考博客:https://www.cnblogs.com/cjoieryl/p/10149748.html 关键是枚举最小质因子...所以构造 ...
- selenium - 截取页面图片和截取某个元素的图
1.截取页面图片并保存 在测试过程中,是有必要截图,特别是遇到错误的时候进行截图. # coding:utf-8 from time import sleep from PIL import Imag ...
- webservice有关application/xop+xml的异常
今天同事调用一个webservice时返回类似错误 响应消息的内容类型 multipart/related; type="application/xop+xml"; boundar ...
- (转)Oracle 包(Package)
本文转载自:http://www.cnblogs.com/lovemoon714/archive/2012/02/29/2373695.html 1.为什么要使用包? 答:在一个大型项目中 ...
- Quartz.net 2.x 学习笔记02-Quartz.net 2.x在MVC站点中结合Log4net的使用
Quartz.net 2.x在MVC站点中结合Log4net的使用 首先新建一个MVC的空站点: 第二步,添加Quartz.net的引用 在搜索处输入quartz.net搜索安装即可(目前是2.3) ...
- 关系数据库元组关系演算语言ALPHA
关系演算 :以数理逻辑中的谓词演算为基础 按谓词变元不同分类 1.元组关系演算:以元组变量作为谓词变元的基本对象元组关系演算语言ALPHA2.域关系演算:以域变量作为谓词变元的基本对象域关系演算语言Q ...