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 ...
随机推荐
- HihoCoder - 1236 Scores (五维偏序,分块+bitset)
题目链接 题意:给定n个五维空间上的点,以及m组询问,每组询问给出一个点,求五个维度都不大于它的点有多少个,强制在线. 神仙题 单独考虑每个维度,把所有点按这个维度上的大小排序,然后分成T块,每块用一 ...
- PS基础教程[1]如何制作微信泡泡
PS是很多朋友都很喜欢额一款图像处理软件,我们可以使用PS制作很多的效果,本系列经验教程的起源就来源于知道中这位朋友问的微信泡泡如何使用,下面就来简单的分享一下. 微信泡泡制作方法 有很多的方法可以制 ...
- computed属性与methods、watched
一.计算属性 new Vue({ data: { message: 'hello vue.js !' }, computed: { reverseMessage: function () { retu ...
- bzoj 4671 异或图——容斥+斯特林反演+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 考虑计算不是连通图的方案,乘上容斥系数来进行容斥. 可以枚举子集划分(复杂度是O(Be ...
- windows64位Oracle安装和PL/SQL配置
折腾了一下午,趟了几个坑,终于用PL/SQL连上了Oracle,晒晒填坑经历. 先去oracle官网下数据库安装文件,官网有登陆验证,如果没注册的话先注册吧.数据库(下载地址http://www.or ...
- dirname 和 basename
dirname 和 basename 命令 [root@localhost /]# cat /tmp/a.sh dirname $0 #获取脚本所在的路径 basename $0 ...
- How to get the MD5 checksum for a file: md5sum, digest, csum, fciv
LINUX: md5sum fileName In Linux, the md5sum utility can be used: aemtux1:/ % md5sum binary.file 0c46 ...
- ByteBuf 类——Netty 的数据容器
1.堆缓冲区 2.直接缓冲区 3.复合缓冲区 —CompositeByteBuf——实现了这个模式,它提供了一 个将多个缓冲区表示为单个合并缓冲区的虚拟表示 适用于 JDK 所使用的一种称为分散/收集 ...
- 杂项:WiKi
ylbtech-杂项:WiKi Wiki是一种在网络上开放且可供多人协同创作的超文本系统,由沃德·坎宁安于1995年首先开发,这种超文本系统支持面向社群的协作式写作,同时也包括一组支持这种写作.沃德· ...
- mapred.JobClient: No job jar file set. User classes may not be found. See JobConf(Class) or JobConf#setJar(String).
报错详情: WARN mapred.JobClient: No job jar file set. User classes may not be found. See JobConf(Class) ...