繁体   English   中英

ERC 20 Token transferFrom 在我的智能合约中不起作用。 也不抛出任何异常

[英]ERC 20 Token transferFrom isn't working in my smart contract. Doesn't throw any Exception either

我在 Solidity 中编写了一份合同,并考虑了以下任务:

  • 用户批准智能合约从他们的钱包中转移一定数量的代币。

  • 智能合约使用此金额转移到作为参数给出的地址。 但它也需要从这个数量中提取 1 个代币才能转移给合约的开发者。

  • 如果一切成功,用户会收到“支付成功”。 信息。

第一步(批准)是使用 React 和 Web3 完成的:

const derc20contract = '0x36850b80ad73fe66216609B9796ed6ceae8BE29F';
const handleClick = async (e) => {
            e.preventDefault();
            const prtmp = await detectEthereumProvider();
            
            // -------------------- Approve Part ------------------------------// 
            const web3 = new Web3(prtmp);
            const erc20contract = new web3.eth.Contract(
                erc20abi, 
                derc20token,
                { from: '0xFromAddress' }
            );

            await erc20contract.methods.approve(derc20contract, web3.utils.toHex(3e18)).send();
            // ---------------------------------------------------------------//

            const contract = new web3.eth.Contract(derc20abi, derc20contract);
            const response = await contract.methods.send_usdt(
                '0xToAddress',
                web3.utils.toHex(3e18)
            )
            .call({ from: '0xFromAddress'});
            console.log(response);
    };



一旦批准成功,function 的第二部分就解决了。 我部署的合约有一个名为 send_usdt 的send_usdt 通过这个 function 是我的智能合约能够转移批准的金额。

/ SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

interface IERC20 {
    function transfer(address _to, uint256 _value) external returns(bool);
    function transferFrom(address _from, address _to, uint _amount) external returns (bool);
    function allowance(address _owner, address _contract) external returns (uint256);
    function balanceOf(address _buyer) external view returns (uint256);
    function approve(address _contract,  uint tokens) external returns (bool);
}

contract DPortalSubscription {

    address private owner;
    mapping(address => uint32) subscription_fees;
    
    constructor()
    { 
        owner = msg.sender; 
    }

    function check_balance() external view returns (uint256)
    {
        // TestToken ( Plasma Bridge ) in Mumbai Network 
        IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
        uint256 balance = usdt.balanceOf(msg.sender);
        return balance;
    }

    function check_sender_address() external view returns (address)
    {
        return msg.sender;
    }

    function check_allowance()external returns(uint256)
    {
        // TestToken ( Plasma Bridge ) in Mumbai Network 
        IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
        uint256 allowance = usdt.allowance(msg.sender, address(this));
        return allowance;
    }

    function send_usdt(address _to, uint256 _amount) external returns (string memory)
    {
        // TestToken ( Plasma Bridge ) in Mumbai Network 
        IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
        require(_amount > 1, "Purchases must be higher than 1 usdt");
        require(usdt.balanceOf(msg.sender) >= _amount, "The buyer doesn't have enough funds");
        require(usdt.allowance(msg.sender, address(this)) >= _amount, "Permissions to transfer tokens denied");
        require(usdt.transferFrom(msg.sender, _to, _amount-1) == true, "Couldn't transfer tokens to seller");
        require(usdt.transferFrom(msg.sender, owner, 1) == true, "Couldn't transfer tokens to support");
        return "Payment successful!";  
    }
}

一旦 React 中 function 的第二部分解析完成,我就会收到“付款成功”的确认信息。 但是代币没有被转移,我在“来自钱包”中保留了相同的金额。 像以前一样“到钱包”和“部署钱包”。


问题出在反应片段中。 通过更改方法call sell的钱可以成功转移。

const response = await contract.methods.send_usdt
(
    '0xToAddress',
    web3.utils.toHex(3e18)
)
.call({ from: '0xFromAddress' });

改为:

const response = await contract.methods.send_usdt
(
    '0xToAddress',
    web3.utils.toHex(3e18),
    { from: '0xFromAddress' }
)
.send();

这有效,但提出了另一个问题。 当我使用前面的call方法时,function 返回“支付成功”。 并使用 sell 方法收到一个对象。

由于“付款成功”不是真的,我想知道当有人使用 call 方法与我的合约交互时是否可以抛出异常。

那可能吗?

尝试将其从 require 语句中移出应该可以工作。

按照@Kuly14 的回答,为了更清楚,您可能需要创建以下 function :

    function send_usdt(address _to, uint256 _amount) external returns (string memory) {
        // TestToken ( Plasma Bridge ) in Mumbai Network 
        IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
        require(_amount > 1, "Purchases must be higher than 1 usdt");
    
        usdt.transferFrom(msg.sender, owner, 1);
        usdt.transferFrom(msg.sender, _to, _amount-1);

        return "Payment successful!";  
    }

注1:只要调用transferFrom方法,如果出错就会跳转到对应的错误。 你不需要处理它们。

注2:我已更改您转移代币的顺序。 首先,我将它们发送给所有者,然后发送给所需的收件人以避免费用支付问题,但如果您更喜欢相反的方式,这是可能的。

我希望这个信息对您有所帮助:)

暂无
暂无

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

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