5 在合约导入已部署的Erc20token进行转账,发生失败

在自己部署了一个实现erc20的代币合约后,我想要新建一个合约对其进行转账,结果失败,我想是不是授权的问题?比如导入其它的erc20的token合约也是如此。使用了SafeERC20。

pragma solidity >=0.6.1<0.9.0;
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract testErc20 is Ownable{
    using SafeERC20 for IERC20;
    address public erc20TestToken=0x423C14e857Ad05E9c76672b00942AF1CDA95d330;
    IERC20 private targetERC20Contract = IERC20(erc20TestToken);
    address public contractMatser;
    //一个合约最多有一个 receive 函数,receive 接收以太函数,(通常是对合约转账)
    receive() external payable { }
    //检查发起者持有多少Token
    function balanceOf(address eoaAddress)public view returns(uint256){
        return targetERC20Contract.balanceOf(eoaAddress);
    }
    //0xaE67336f06B10fbbb26F31d31AbEA897290109B9
    //0x986f2707BD30A9926D17F624b5497c178DAE51D5
    //授权
    function approveSend(address toAddress, uint256 amount)public{
        require(balanceOf(msg.sender)>=amount,"SendAddress haven't a token!");
        targetERC20Contract.safeApprove(toAddress, amount);
    }
    //转账
    function sendToken(address from,address to,uint256 amount)public payable{
        require(balanceOf(from)>0,"From address haven't a token!");
        targetERC20Contract.safeTransferFrom(msg.sender, to, amount);
    }
}
请先 登录 后评论

5 个回答

0527

报错信息

请先 登录 后评论
Tiny熊
  擅长:智能合约,以太坊

approveSend 实现的是: testErc20 合约地址 授权给 toAddress 地址。

sendToken 需要的是 msg.sender (交易发起者) 对 testErc20 合约 有授权。

两个授权不匹配, 因此转账失败。
你需要先进行用户向 testErc20 合约地址 授权, 或者 sendToken 里直接使用 transfer 从合约转账。

请先 登录 后评论
Meta - 风是自由的,你也是

targetERC20Contract.safeApprove(toAddress, amount);
意思是把testErc20合约的 token授权给toAddress;而sendToken()函数是消耗的是msg.sender对testErc20合约的授权。

其实授权你要去erc20TestToken这个合约直接调用safeApprove()方法,授权给testErc20合约;之后在testErc20合约调用sendToken()函数就可以了。

除非你 testErc20合约持有token,否则 approveSend()函数用不到的。

请先 登录 后评论
? or ?

这是我更改后的,但是任然有报错

//SPDX-License-Identifier: MIT
pragma solidity >=0.6.1<0.9.0;
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract testErc20 is Ownable{
    using SafeERC20 for IERC20;
    address public erc20TestToken=0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1;
    //通过这里获取到测试Token
    IERC20 private targetERC20Contract = IERC20(erc20TestToken);
    address public contractMatser;
    //一个合约最多有一个 receive 函数,receive 接收以太函数,(通常是对合约转账)
    receive() external payable { }
    //检查发起者持有多少Token
    function balanceOf(address eoaAddress)public view returns(uint256){
        return targetERC20Contract.balanceOf(eoaAddress);
    }
    //0xaE67336f06B10fbbb26F31d31AbEA897290109B9   //该地址拥有测试代币
    //0x986f2707BD30A9926D17F624b5497c178DAE51D5   //待接收地址

    //返回当前合约地址
    function getThisAddress()public view returns(address){
        return address(this);
    }

    //交易发起者发起授权
    function approveSend(uint256 amount)public payable{
        require(balanceOf(msg.sender)>=amount,"SendAddress haven't a token!");
        targetERC20Contract.safeApprove(msg.sender, amount);
    }
    //转账
    function sendToken(address from,address to,uint256 amount)public payable{
        require(balanceOf(from)>0,"From address haven't a token!");
        targetERC20Contract.safeTransferFrom(msg.sender, to, amount);
    }

    //给予合约授权
    function approvalContract(uint256 amount)public payable{
        require(balanceOf(msg.sender)>=amount,"SendAddress haven't a token!");
        targetERC20Contract.safeApprove(address(this),amount);
    }

    //合约转账
    function contractSend(address to,uint256 amount)public payable{
        targetERC20Contract.safeTransferFrom(address(this),to,amount);
    }
}
请先 登录 后评论
? or ?

并且当授权出来时出现是这样的:

image.png

请先 登录 后评论
  • 4 关注
  • 0 收藏,4258 浏览
  • ? or ? 提出于 2022-11-30 15:59