【问题标题】:Implementing buying and selling in Solidity在 Solidity 中实现买卖
【发布时间】:2021-07-28 06:18:33
【问题描述】:

所以我希望能够购买/出售代币,但也希望用户能够将 eth 发送到我的合约钱包并接收我的代币作为交换。我相信我已经为买家和卖家准备好了代码,可以一起进行交易,不要认为我有东西可以让某人接收代币以向我发送以太坊。我想在一开始就让人们向我发送 eth 以获得一些设定为基础价值的硬币

pragma solidity 0.4.22;

contract ERC20Basic {

    string public constant name = "Community Token";
    string public constant symbol = "COMM";
    uint8 public constant decimals = 1;  


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


    mapping(address => uint256) balances;

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

    using SafeMath for uint256;


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

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

    function transfer(address receiver, uint numTokens) public 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, uint numTokens) public returns (bool) {
        allowed[msg.sender][delegate] = numTokens;
        emit Approval(msg.sender, delegate, numTokens);
        return true;
    }

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

    function transferFrom(address owner, address buyer, uint numTokens) public 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;
    }
}

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;
    }
}

【问题讨论】:

    标签: blockchain ethereum solidity remix


    【解决方案1】:

    一个非常基本的买卖例子:

    pragma solidity ^0.8;
    
    contract ERC20Basic{
        uint256 public constant tokenPrice = 5; // 1 token for 5 wei
        
        function buy(uint256 _amount) external payable {
            // e.g. the buyer wants 100 tokens, needs to send 500 wei
            require(msg.value == _amount * tokenPrice, 'Need to send exact amount of wei');
            
            /*
             * sends the requested amount of tokens
             * from this contract address
             * to the buyer
             */
            transfer(msg.sender, _amount);
        }
        
        function sell(uint256 _amount) external {
            // decrement the token balance of the seller
            balances[msg.sender] -= _amount;
            increment the token balance of this contract
            balances[address(this)] += _amount;
    
            /*
             * don't forget to emit the transfer event
             * so that external apps can reflect the transfer
             */
            emit Transfer(msg.sender, address(this), _amount);
            
            // e.g. the user is selling 100 tokens, send them 500 wei
            payable(msg.sender).transfer(amount * tokenPrice);
        }
    }
    

    这将允许任何用户从/向您的合约购买或出售代币。您的合约需要拥有这些代币才能将它们出售给用户。此外,您的合约需要有足够的 ETH 才能从用户那里回购代币。

    您可以扩展此代码来实现

    • 有权更改价格的合同所有者
    • 买卖价格不同
    • 费用
    • 最小/最大金额(每笔交易、每位用户、每天……)
    • 根据msg.value 计算代币数量(用户不必知道确切的数量)
    • 等等……

    请注意,我的 sn-p 使用的是 Solidity 0.8,其中会自动防止整数溢出。问题是使用已弃用的 Solidity 0.4,因此您需要使用 SafeMath,使用 require/assert 检查值或升级到 Solidity 0.8 以达到相同的结果。

    【讨论】:

    • 在你给出的这个例子中,这个代码是否也接受BNB?
    • @EvertonFigueiredo 在 BSC 网络上(其中 BNB 是本机令牌) - 是的。在以太坊网络上(BNB 是 ERC-20 代币) - 没有。
    • 警告!合约执行期间遇到错误 [out of gas] ,当我尝试发送到我的合约时出现此错误,你知道如何告诉我为什么吗?
    • @EvertonFigueiredo 这是一个非常笼统的错误消息,它可能是由从你的合约的不同实施到不正确使用的任何原因引起的(也许你正试图从没有它们的合约中购买代币? 或者您向buy() 函数发送了不正确的wei 数量?)。请ask 一个单独的问题,您提供一个最小的可重现示例,以便其他人能够按照您的描述遇到与您相同的错误。
    猜你喜欢
    • 1970-01-01
    • 2021-11-05
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多