zoukankan      html  css  js  c++  java
  • Solidity transfer vs send 区别

    原文地址: 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!)
  • 相关阅读:
    java-Date、String、Calendar转化
    java -日期
    eclipse安装ADT
    Echarts-axislabel文字过长导致显示不全或重叠
    Echarts-柱状图柱图宽度设置
    Echarts-画叠加柱状图,双折线图
    Echarts-画堆积柱状图,折线图
    Echarts-画柱状,折线图
    windows系统激活-使用微软官方公布的kms client setup key安装或安装后使用slmgr导入
    Office 2013 Pro Plus Vol激活
  • 原文地址:https://www.cnblogs.com/huahuayu/p/8650052.html
Copyright © 2011-2022 走看看