{"content":{"title":"receive payable 里面尽量避免写代码,以免其他合约调用transfer 不成功","body":"## receive() payable 里面尽量避免写代码,以免其他合约调用transfer 不成功\r\n缘起:最近调试一段solidity代码,本来想测试在收款的时候,记录一个receive 和发出一个log,哪个消耗gas更大\r\n- 如下图,我定义了两个contract, TestTransfer 中的sendOut函数会使用transfer转账到TransferCount 合约.\r\n    - 第一步 使用remix 测试,总是不成功.\r\n    - 第二步 使用remix直接给TransferCount转账能成功\r\n    - 修改代码,注释掉 TransferCount recieve() 里面的代码,重做第一步测试就能成功.\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2024/09/J7UUM1ko66e3ffb6b3881.png)\r\n\r\n\r\n\r\n\r\n### 转账失败的\r\n```solidity\r\npragma solidity >0.8.0 ;\r\n\r\ncontract TransferCount {\r\n    uint public fallbackCount = 0;\r\n    uint public receiveCount = 0;\r\n    constructor() payable{\r\n\r\n    }\r\n    function deposit() payable external{\r\n\r\n    }\r\n    receive() external payable {\r\n       //这里增加代码,可能导致合约TestTransfer.sendOut 中调用 address.transfer 因为gas不足调用失败\r\n        receiveCount ++;\r\n    }\r\n    fallback() external payable{\r\n        fallbackCount ++;\r\n    }\r\n}\r\n\r\ncontract TestTransfer{\r\n    uint public fallbackCount = 0;\r\n    uint public receiveCount = 0;\r\n    address payable public  tc;\r\n    receive() external payable {\r\n        receiveCount ++;\r\n    }\r\n    fallback() external payable{\r\n        fallbackCount ++;\r\n    }\r\n\r\n\r\n    constructor(address payable addr) payable {\r\n        tc = addr;\r\n\r\n    }\r\n\r\n    function sendOut(uint amount ) external{\r\n        require(amount  <= address(this).balance, \"insufficient balance\");\r\n        payable(tc).transfer(amount);\r\n       \r\n    }\r\n}\r\n```\r\n\r\n### 转账成功\r\n在receive中写状态变量，gas太高，超过23000 gas。 不过可以发个event，不涉及状态变量。\r\n如下图\r\n```solidity\r\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\nevent Receive(address from, uint256 amount);\r\ncontract Target{\r\n    // gas 22625\r\n    receive() payable external{\r\n        emit Receive(msg.sender,msg.value);\r\n    }\r\n}\r\ncontract TestTransfer{\r\n    function send(address target )  public payable {\r\n        payable(target).transfer(msg.value);\r\n    }\r\n}\r\n```"},"author":{"user":"https://learnblockchain.cn/people/22222","address":null},"history":"bafkreiddcjtoqz7spivx7dmxw2d5nyopdki5biyos4onra4hxemoacytzu","timestamp":1726834287,"version":1}