receive payable 里面尽量避免写代码,以免其他合约调用transfer 不成功
receive() payable 里面尽量避免写代码,以免其他合约调用transfer 不成功
缘起:最近调试一段solidity代码,本来想测试在收款的时候,记录一个receive 和发出一个log,哪个消耗gas更大
- 如下图,我定义了两个contract, TestTransfer 中的sendOut函数会使用transfer转账到TransferCount 合约.
- 第一步 使用remix 测试,总是不成功.
- 第二步 使用remix直接给TransferCount转账能成功
- 修改代码,注释掉 TransferCount recieve() 里面的代码,重做第一步测试就能成功.
转账失败的
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);
}
}
版权声明
本文仅代表作者观点,不代表区块链技术网立场。
本文系作者授权本站发表,未经许可,不得转载。
上一篇:加密货币与Web3经济:塑造未来数字经济的基石 下一篇:Safe 多签钱包介绍
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。