ethereum - 如何在 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];
}
}