首页 > 解决方案 > 如何在 ERC-20 标准的 transferFrom 方法中实现津贴功能?

问题描述

正如标题所说,我正在从头开始实施 ERC-20 代币,但我一直在实施津贴。我想让向另一个用户发送代币的用户能够花费其他用户给他/她的津贴(假设用户自己没有足够的代币)。

我的代码如下;你能看一下它并给我一些关于如何实现它的提示吗?我指的是transferFrom函数(那里有一个TODO描述我想要做的事情)。

先感谢您!

pragma solidity >=0.4.17; // from https://eips.ethereum.org/EIPS/eip-20

contract MyCoin {

  mapping(address => uint256) balances; // stores balances of all token holders
  mapping(address => mapping(address => uint256)) allowances; // stores allowances of all token holders

  // events as defined by the ERC-20 standard
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 _value
  );

  event Approval(
    address indexed _owner,
    address indexed _spender,
    uint256 _value
  );

  // contract variables
  address owner;
  uint256 unassignedTokens = 21000000; // inspired by the total number of Bitcoins

  // constructor which gives 50% of the token to the contract owner (deployer)
  constructor() public
  {
    owner = msg.sender;
    // give the owner 50% of the tokens
    balances[owner] += (unassignedTokens / 2);
    unassignedTokens -= (unassignedTokens / 2);
  }

  function issue(address _to, uint256 _value) public returns (bool success)
  {
    if (msg.sender != owner) // only the owner can issue tokens
    {
      return false; // TODO: maybe throw an exception here
    }
    if (unassignedTokens < _value)
    {
      return false; // TODO: maybe throw an exception here?
    }
    balances[_to] += _value;
    unassignedTokens -= _value;
  }

  function name() public view returns (string memory)
  {
    return "MyCoin";
  }

  function symbol() public view returns (string memory)
  {
    return "MY";
  }

  function decimals() public view returns (uint8)
  {
    return 18; // 18 decimals, like wei
  }

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

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

  function transfer(address _to, uint256 _value) public returns (bool success)
  {
    if (balances[msg.sender] < _value)
    {
      return false; // TODO: I should throw an expection here
    }
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    emit Transfer(msg.sender, _to, _value); // I must do this according to the specification
    return true;
  }

  function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
  {
    if ((_from != msg.sender) || (_from != owner)) // only the owner of the token or the token creator can send tokens
    {
      return false;
    }
    // TODO: Now I'd have to check if balances[_from] < _value
    // but I'd also have to check if allowances[_from] has any allowances and
    // if it does, then I'd either have to spend a fraction of one allowance
    // or aggregate multiple allowances from multiple different addresses
    // in order to transfer the tokens. Since I can't iterate over allowances
    // mapping, I don't know how to implement this.
    balances[_from] -= _value;
    balances[_to] += _value;
    allowances[_from][msg.sender] -= _value;
    emit Transfer(_from, _to, _value);
    return true;
  }

  function approve(address _spender, uint256 _value) public returns (bool success)
  {
    // TODO: Check that balances[msg.sender] >= _value ?
    allowances[_spender][msg.sender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  function allowance(address _owner, address _spender) public view returns (uint256 remaining)
  {
    return allowances[_spender][_owner];
  }

}

标签: ethereumsoliditysmartcontractserc20

解决方案


推荐阅读