I noticed that this function, in ERC20.sol, is public:
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
return true;
}
I’m wondering why it is safe to be defined as public? I think the answer is that (1) the tokens can only be transferred from the sender’s account and since the sender is calling the method on the contract, it has to be pubic for the contract to function. As well, (2), there is no way for anyone to transfer tokens that they do not own own.
Am I correct on both 1 and 2 above?
2 Likes
Hi @Steve_L
- Tokens can only be transferred from the senders account, please note, it is the sender who sets the allowance (the withdrawer calls
transferFrom
not the sender). transferFrom
needs to be public to be called by other contracts and external accounts.
- There is meant to be no way for an account to withdraw tokens that they do not have an allowance for.
I have provided more detail to clarify my answer below:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transferfrom
The transferFrom
method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies.
The withdraw workflow:
- An account (token holder) sets an allowance for an account
- The account with an allowance (a contract or an external account) can then transfer (withdraw) an amount of tokens within the set allowance.
The allowance is set by an account (token holder) calling the approve function (token holder is the msg.sender
).
function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
An account can only transfer an amount of tokens within the set allowance by calling transferFrom
(withdrawer is the msg.sender
)
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
return true;
}
The withdraw is deemed safe because tokens can only be transferred within the amount of tokens that the sender holds (checked when _balances
is decreased) and within the set allowance for the account (checked when _allowances
is decreased). (Otherwise either transaction would revert with reason "SafeMath: subtraction overflow"
).
transferFrom
needs to be public
to allow the function to be called by other contracts and external accounts.
Please note, the sender (the token holder) doesn't call transferFrom
, the sender (the token holder) sets the allowance by calling approve
.
Let me know if you need more information.
2 Likes
Great! Thank you @abcoathup.
2 Likes
Keep the questions coming @Steve_L
This is great information for the community.
Housekeeping: I marked my reply as the solution.
1 Like