繁体   English   中英

如何可靠地从我的合约中提取所有代币

[英]how to withdraw all tokens from the my contract in solidity

谁能帮我?

我创建了一个基本合同。但不知道取款 function。请帮助我。谢谢大家 我尝试创建一个基本 function 但它不起作用

function withdraw() public {
    msg.sender.transfer(address(this).balance);
}
msg.sender.transfer(address(this).balance);

此行提取本机余额(如果您的合约在以太坊网络上,则为 ETH)。


要提取代币余额,您需要对代币合约执行transfer()函数。 因此,为了提取所有代币,您需要对所有代币合约执行transfer()函数。

您可以创建一个函数,根据您作为输入传递的代币合约地址提取任何 ERC-20 代币。

pragma solidity ^0.8;

interface IERC20 {
    function transfer(address _to, uint256 _amount) external returns (bool);
}

contract MyContract {
    function withdrawToken(address _tokenContract, uint256 _amount) external {
        IERC20 tokenContract = IERC20(_tokenContract);
        
        // transfer the token from address of this contract
        // to address of the user (executing the withdrawToken() function)
        tokenContract.transfer(msg.sender, _amount);
    }
}

请注意,这段代码是不安全的——任何人都可以执行withdrawToken()函数。 如果要在生产中运行它,请添加某种形式的身份验证,例如Ownable模式。

不幸的是,由于令牌标准(以及一般的以太坊网络)的设计方式,没有简单的方法可以“一次转移所有令牌”,因为没有简单的方法来获得“地址的非零令牌余额”。 您在区块链浏览器中看到的(例如,一个地址持有代币 X、Y 和 Z)是无法在链上执行的聚合的结果。

假设你的合约是 ERC20,EIP 20 中定义的transfer函数表示:

将 _value 数量的代币转移到地址 _to,并且必须触发 Transfer 事件。 如果消息调用者的帐户余额没有足够的代币可以花费,则该函数应该抛出。

注意 0 值的传输必须被视为正常传输并触发 Transfer 事件。

函数传输(地址 _to,uint256 _value)公开返回(布尔成功)

当您调用transfer的实现时,您基本上是在更新调用者和接收者的余额。 它们的余额通常保存在映射/查找表数据结构中。

请参阅ConsenSys 的transfer实现

  • 由于它是一个基本合约,我认为它不是erc20币,如果你只是想提款:

     function withdraw(uint amount) external onlyOwner{ (bool success,)=owner.call{value:amount}(""); require(success, "Transfer failed;"); }

此 function 只能由所有者调用。

  • 如果您想在紧急情况下提取全部余额:

     function emergencyWithdrawAll() external onlyWhenStopped onlyOwner { (bool success,)=owner.call{value:address(this).balance}(""); require(success,"Transfer failed;"); }

这个 function 有两个修饰符: onlyWhenStopped onlyOwner

在以下情况下使用紧急停止模式

  • 你想有能力暂停你的合同。
  • 您希望保护关键功能免受未被发现的错误的滥用。
  • 你想为潜在的失败准备你的合同。

修饰符:

modifier onlyOwner() {
    // owner is storage variable is set during constructor
    if (msg.sender != owner) {
      revert OnlyOwner();
    }
    _;
  }
  • 对于onlyWhenStopped ,我们设置了一个 state 变量:

     bool public isStopped=false;

然后修饰符

modifier onlyWhenStopped{
    require(isStopped);
    _;
  }

我来这里是为了找到一个解决方案,让所有者可以撤回任何意外发送到我的智能合约地址的代币。 我相信它对其他人有用:

 /**
 * @dev transfer the token from the address of this contract  
 * to address of the owner 
 */
function withdrawToken(address _tokenContract, uint256 _amount) external onlyOwner {
    IERC20 tokenContract = IERC20(_tokenContract);

    // needs to execute `approve()` on the token contract to allow itself the transfer
    tokenContract.approve(address(this), _amount);

    tokenContract.transferFrom(address(this), owner(), _amount);
}

我面临同样的问题,但我的合同已部署,如何使用提款功能升级我的合同。

请帮忙

期待中的感谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM