receive payable 里面尽量避免写代码,以免其他合约调用transfer 不成功

  • jinglin
  • 更新于 2024-09-20 20:11
  • 阅读 363

receive()payable里面尽量避免写代码,以免其他合约调用transfer不成功缘起:最近调试一段solidity代码,本来想测试在收款的时候,记录一个receive和发出一个log,哪个消耗gas更大如下图,我定义了两个contract,TestTransfer中的se

receive() payable 里面尽量避免写代码,以免其他合约调用transfer 不成功

缘起:最近调试一段solidity代码,本来想测试在收款的时候,记录一个receive 和发出一个log,哪个消耗gas更大

  • 如下图,我定义了两个contract, TestTransfer 中的sendOut函数会使用transfer转账到TransferCount 合约.
    • 第一步 使用remix 测试,总是不成功.
    • 第二步 使用remix直接给TransferCount转账能成功
    • 修改代码,注释掉 TransferCount recieve() 里面的代码,重做第一步测试就能成功.

image.png

转账失败的

pragma solidity >0.8.0 ;

contract TransferCount {
    uint public fallbackCount = 0;
    uint public receiveCount = 0;
    constructor() payable{

    }
    function deposit() payable external{

    }
    receive() external payable {
       //这里增加代码,可能导致合约TestTransfer.sendOut 中调用 address.transfer 因为gas不足调用失败
        receiveCount ++;
    }
    fallback() external payable{
        fallbackCount ++;
    }
}

contract TestTransfer{
    uint public fallbackCount = 0;
    uint public receiveCount = 0;
    address payable public  tc;
    receive() external payable {
        receiveCount ++;
    }
    fallback() external payable{
        fallbackCount ++;
    }

    constructor(address payable addr) payable {
        tc = addr;

    }

    function sendOut(uint amount ) external{
        require(amount  <= address(this).balance, "insufficient balance");
        payable(tc).transfer(amount);

    }
}

转账成功

在receive中写状态变量,gas太高,超过23000 gas。 不过可以发个event,不涉及状态变量。 如下图

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
event Receive(address from, uint256 amount);
contract Target{
    // gas 22625
    receive() payable external{
        emit Receive(msg.sender,msg.value);
    }
}
contract TestTransfer{
    function send(address target )  public payable {
        payable(target).transfer(msg.value);
    }
}
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
jinglin
jinglin
江湖只有他的大名,没有他的介绍。