简体   繁体   English

Solidity 转移问题

[英]Solidity Transfer Issue

i have created an ERC20 token and a second contract called Vendor that is only supposed to receive ETH and then call the transfer function of the ERC20 contract to send the tokens to the buyer.我创建了一个 ERC20 代币和第二个名为 Vendor 的合约,它只应该接收 ETH,然后调用 ERC20 合约的转账 function 将代币发送给买方。

Through ether.js i call the Buy function on the vendor contract, sending the amount of eth as follows通过 ether.js,我在供应商合同上调用 Buy function,发送的 eth 数量如下

async function buy() {
const request = await vendorContract.buyTokens(
    {
         from: accounts[0],
         value: ethers.utils.parseUnits("0.1") 
    }
);
}

As soon as the Vendor contract receives the transaction, it checks that the amount is higher than 0, and checks the Vendor contract balance to make sure it is going to be able to pay, as follows一旦 Vendor 合约收到交易,它会检查金额是否高于 0,并检查 Vendor 合约余额以确保它能够支付,如下所示

function buyTokens() public payable returns (uint256 tokenAmount) {
require(msg.value > 0, "Send ETH to buy some tokens");

uint256 amountToBuy = msg.value * tokensPerEth;

// check if the Vendor Contract has enough amount of tokens for the transaction
uint256 contractBalance = ercToken.balanceOf(address(this));
require(contractBalance >= amountToBuy, "Vendor contract has not enough tokens in its 
balance");

// Transfer token to the msg.sender
(bool sent) = ercToken.transfer(msg.sender, amountToBuy);
require(sent, "Failed to transfer token to user");

// emit the event
 emit BuyTokens(msg.sender, msg.value, amountToBuy);

return amountToBuy;
}

And untill now, everything works, then, the ERC20 Smart Contract should transfer the amount of tokens the user bought to the user's address as follows到目前为止,一切正常,然后,ERC20 智能合约应该将用户购买的代币数量转移到用户的地址,如下所示

function transfer(address to, uint256 amount) public virtual override returns (bool) {
    _transfer(msg.sender, to, amount * 1e18);
    return true;

The ERC20 smart contract transfer function sets the caller equal to the msg.sender, in this case, our Vendor smart contract, passes the "to" address and multiplies the amount * decilams (18) and then invokes the _transfer function ERC20 智能合约转账 function 将调用者设置为 msg.sender,在这种情况下,我们的 Vendor 智能合约,传递“to”地址并乘以金额 * 分位数 (18),然后调用 _transfer ZC1C425268E68385D1AB5074C17A94F14

    function _transfer(
    address from,
    address to,
    uint256 amount
    ) internal virtual {
    require(from != address(0), "ERC20: transfer from the zero address");
    require(to != address(0), "ERC20: transfer to the zero address");

    _beforeTokenTransfer(from, to, amount);

    uint256 fromBalance = _balances[from];
    require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
    unchecked {
        _balances[from] = fromBalance - amount;
       
        _balances[to] += amount;
    }

    emit Transfer(from, to, amount);

    _afterTokenTransfer(from, to, amount);
}

And this is where my issue starts, even if both ERC20 contract and Vendor contract got 1.000.000.000 tokens in their balance, the _transfer function fails saying the amount exceeds the balance.这就是我的问题开始的地方,即使 ERC20 合约和供应商合约的余额中都有 1.000.000.000 个代币,_transfer function 未能说明金额超过余额。 Any idea why?知道为什么吗?

From the transfer function, you are passing the msg.sender as from to the _transfer function.transfer function,您将msg.sender作为from传递给_transfer function。 Which means you are trying to send tokens to a msg.sender from a msg.sender.这意味着您正在尝试从 msg.sender 向 msg.sender 发送令牌。

So thats why contract is giving you the "ERC20: transfer amount exceeds balance" error from this line require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");所以这就是为什么合约在这条线上给你“ERC20:转账金额超过余额”错误require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); fromBalance is zero because it didnt recieved any tokens yet. fromBalance 为零,因为它还没有收到任何令牌。

What you want to do here is this;你想在这里做的是这个;

on the transfer function, you should pass the vendorContract like this;transfer function 时,您应该像这样通过vendorContract

`function transfer(address to, uint256 amount) public virtual override returns (bool) {
_transfer(vendorContract, to, amount * 1e18);
return true;`

That way the from argument on the _transfer function will be the vendor contract and everything should work as intended.这样, _transfer function 上的from参数将成为供应商合同,一切都应按预期工作。

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

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