Hi, I am trying to understand what the difference is between the transfer functions on line 115-117:
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
and on lines 208-216:
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
Ohhh, you know, for a standard ERC20 contract, there are two functions to transfer token:
transfer(to, amount)
transfer(from, to, amount)
so there will have some of the the same code, so in order to reuse these logic, _transfer(sender, recipient, amount) comes. And transfer() is a public function you can call, but for _transfer(), it is a internal function, so you can not access to it directly.
That is my opinion, if I understand wrongly, please correct me.
@Skyge hi and thanks. It looks like the second transfer function is the actual transfer function that updates the state. I am not sure what the first one does as it returns a bool; it looks like it is just whether or not there was a transfer to a specific address and amount returning True/False?
As @Skyge said (thanks as always @skyge ) there are two transfer functions which return bool as defined in the EIP (see: https://eips.ethereum.org/EIPS/eip-20), transfer and transferFrom, which in the OpenZeppelin Contracts ERC20 implementation call a single internal _transfer function which does the actual work (and changes the state).
@abcoathup thank you. So is my understand of the different transfers below correct?
function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; This just returns whether a transfer took place or not?
2. function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; This returns a bool on whether or the internal allowance transfer took place?
3. function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); This is an actual transfer which will update the state.