微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 BNB 从合约购买代币时的问题

如何解决使用 BNB 从合约购买代币时的问题

我正在创建这个智能合约,它会创建所有代币并将其添加到我的钱包中。 然后我将钱包中的所有代币发送到我的合约中。

但是,当我从另一个钱包发送 BNB 用于合约时,我希望他归还我合约中的一些代币。

当我这样做时,传输失败并发送以下错误消息:

警告!合约执行过程中遇到错误 [out of gas]

Queria saber se estou fazendo algo errado,ou como devo fazer para que meu contrato tenha gas

交易详情:https://testnet.bscscan.com/tx/0x7ef36e49e3c6f77716aee79cefbde6c298c3ddeef16ed12dbe613573661135bb

智能合约:

pragma solidity ^0.8.0;

interface IERC20 {

function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner,address spender) external view returns (uint256);

function transfer(address recipient,uint256 amount) external returns (bool);
function approve(address spender,uint256 amount) external returns (bool);
function transferFrom(address sender,address recipient,uint256 amount) external returns (bool);


event Transfer(address indexed from,address indexed to,uint256 value);
event Approval(address indexed owner,address indexed spender,uint256 value); }


contract ERC20Basic is IERC20 {

string public constant name = "ByeSeel";
string public constant symbol = "BYS";
uint8 public constant decimals = 18;


event Approval(address indexed tokeNowner,uint tokens);
event Transfer(address indexed from,uint tokens);


mapping(address => uint256) balances;

mapping(address => mapping (address => uint256)) allowed;

uint256 totalSupply_ = 100 * 10 ** 18;

using SafeMath for uint256;

constructor() public {
balances[msg.sender] = totalSupply_;
}

function totalSupply() public override view returns (uint256) {
return totalSupply_;
}

function balanceOf(address tokeNowner) public override view returns (uint256) {
    return balances[tokeNowner];
}

function transfer(address receiver,uint256 numTokens) public override returns (bool) {
    require(numTokens <= balances[msg.sender]);
    balances[msg.sender] = balances[msg.sender].sub(numTokens);
    balances[receiver] = balances[receiver].add(numTokens);
    emit Transfer(msg.sender,receiver,numTokens);
    return true;
}

function approve(address delegate,uint256 numTokens) public override returns (bool) {
    allowed[msg.sender][delegate] = numTokens;
    emit Approval(msg.sender,delegate,numTokens);
    return true;
}

function allowance(address owner,address delegate) public override view returns (uint) {
    return allowed[owner][delegate];
}

function transferFrom(address owner,address buyer,uint256 numTokens) public override returns (bool) {
    require(numTokens <= balances[owner]);
    require(numTokens <= allowed[owner][msg.sender]);

    balances[owner] = balances[owner].sub(numTokens);
    allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
    balances[buyer] = balances[buyer].add(numTokens);
    emit Transfer(owner,buyer,numTokens);
    return true;
}

event Received(address,uint);
 receive() external payable {
 emit Received(msg.sender,msg.value);
}

 }

library SafeMath {
function sub(uint256 a,uint256 b) internal pure returns (uint256) {
  assert(b <= a);
  return a - b;
}

function add(uint256 a,uint256 b) internal pure returns (uint256) {
  uint256 c = a + b;
  assert(c >= a);
  return c;
} }

contract DEX {

event Bought(uint256 amount);
event Sold(uint256 amount);


IERC20 public token;

constructor() public {
    token = new ERC20Basic();
}

function buy() payable public {
    uint256 amountTobuy = msg.value;
    uint256 dexBalance = token.balanceOf(address(this));
    require(amountTobuy > 0,"You need to send some Ether");
    require(amountTobuy <= dexBalance,"Not enough tokens in the reserve");
    token.transfer(msg.sender,amountTobuy);
    emit Bought(amountTobuy);
}

function sell(uint256 amount) public {
    require(amount > 0,"You need to sell at least some tokens");
    uint256 allowance = token.allowance(msg.sender,address(this));
    require(allowance >= amount,"Check the token allowance");
    token.transferFrom(msg.sender,address(this),amount);
    msg.sender.transfer(amount);
    emit Sold(amount);
}

}

解决方法

根据 BscScan 上的交易明细,您尝试发送 0.1 个 BNB 并且没有调用任何函数。

您的合约没有接受传入 BNB 的 receive()fallback() 函数。

所以您需要做的就是实现 receive() 函数。请注意允许此函数接受 BNB 的 payable 修饰符。

contract ERC20Basic is IERC20 {
    // rest of your code

    receive() external payable {
        // can call the buy() function
        buy();
    }
}

您可以在 screenshot 中看到,当您向合约发送 100 wei(或 BNB 的情况下为 100 jager)时,receive() 函数执行 buy() 函数并生成Bought 事件日志。

这是在您的合约中实现的全部代码:

pragma solidity ^0.8.0;

interface IERC20 {

function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner,address spender) external view returns (uint256);

function transfer(address recipient,uint256 amount) external returns (bool);
function approve(address spender,uint256 amount) external returns (bool);
function transferFrom(address sender,address recipient,uint256 amount) external returns (bool);


event Transfer(address indexed from,address indexed to,uint256 value);
event Approval(address indexed owner,address indexed spender,uint256 value);
    
}


contract ERC20Basic is IERC20 {

string public constant name = "ByeSeel";
string public constant symbol = "BYS";
uint8 public constant decimals = 18;


//event Approval(address indexed tokenOwner,uint tokens);
//event Transfer(address indexed from,uint tokens);


mapping(address => uint256) balances;

mapping(address => mapping (address => uint256)) allowed;

uint256 totalSupply_ = 100 * 10 ** 18;

using SafeMath for uint256;

constructor() public {
balances[msg.sender] = totalSupply_;
}

function totalSupply() public override view returns (uint256) {
return totalSupply_;
}

function balanceOf(address tokenOwner) public override view returns (uint256) {
    return balances[tokenOwner];
}

function transfer(address receiver,uint256 numTokens) public override returns (bool) {
    require(numTokens <= balances[msg.sender]);
    balances[msg.sender] = balances[msg.sender].sub(numTokens);
    balances[receiver] = balances[receiver].add(numTokens);
    emit Transfer(msg.sender,receiver,numTokens);
    return true;
}

function approve(address delegate,uint256 numTokens) public override returns (bool) {
    allowed[msg.sender][delegate] = numTokens;
    emit Approval(msg.sender,delegate,numTokens);
    return true;
}

function allowance(address owner,address delegate) public override view returns (uint) {
    return allowed[owner][delegate];
}

function transferFrom(address owner,address buyer,uint256 numTokens) public override returns (bool) {
    require(numTokens <= balances[owner]);
    require(numTokens <= allowed[owner][msg.sender]);

    balances[owner] = balances[owner].sub(numTokens);
    allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
    balances[buyer] = balances[buyer].add(numTokens);
    emit Transfer(owner,buyer,numTokens);
    return true;
}

event Received(address,uint);
 receive() external payable {
 emit Received(msg.sender,msg.value);
}

 }

library SafeMath {
function sub(uint256 a,uint256 b) internal pure returns (uint256) {
  assert(b <= a);
  return a - b;
}

function add(uint256 a,uint256 b) internal pure returns (uint256) {
  uint256 c = a + b;
  assert(c >= a);
  return c;
} }

contract DEX {

    event Bought(uint256 amount);
    event Sold(uint256 amount);
    
    
    IERC20 public token;
    
    constructor() public {
        token = new ERC20Basic();
    }
    
    function buy() payable public {
        uint256 amountTobuy = msg.value;
        uint256 dexBalance = token.balanceOf(address(this));
        require(amountTobuy > 0,"You need to send some Ether");
        require(amountTobuy <= dexBalance,"Not enough tokens in the reserve");
        token.transfer(msg.sender,amountTobuy);
        emit Bought(amountTobuy);
    }
    
    function sell(uint256 amount) public {
        require(amount > 0,"You need to sell at least some tokens");
        uint256 allowance = token.allowance(msg.sender,address(this));
        require(allowance >= amount,"Check the token allowance");
        token.transferFrom(msg.sender,address(this),amount);
        payable(msg.sender).transfer(amount);
        emit Sold(amount);
    }
    
    receive() external payable {
        buy();
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。