The problem is what allowance
and approve
are really doing?
And what is _spender
and what is it doing?
Is there anybody who can explain it to me?
contract Token {
uint256 public totalSupply;
function balanceOf(address _owner) constant returns (uint256 balance);
function transfer(address _to, uint256 value) returns (bool success);
function transferFrom(address _from, address _to, uint256 value) returns (bool success);
function approve(address _spender, uint256 _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
Approve is a function used to give permission the spender can be anyone an exchange or EOA to withdraw as many times from your token contract up to the _value . You can check this reference here. Follow this answer to receive notifications.
The ERC-20 standard allows an address to give an allowance to another address to be able to retrieve tokens from it. This getter returns the remaining number of tokens that the spender will be allowed to spend on behalf of owner .
ERC20 defines the functions balanceOf , totalSupply , transfer , transferFrom , approve , and allowance . It also has a few optional fields like the token name, symbol, and the number of decimal places with which it will be measured.
The allowance() function returns the token amount remaining, which the spender is currently allowed to withdraw from the owner's account. This function returns the remaining balance of tokens from the allowed mapping.
what allowance and approve are doing really?
Let's assume we have user A and user B. A has 1000 tokens and want to give permission to B to spend 100 of them.
approve(address(B), 100)
allowance(address(A), address(B))
transferFrom(address(A), address(B), 100)
Allowance
means that we can grant approval to another contract or address to be able to transfer our ERC20 tokens. And this requirement is common in distributed applications, such as escrows, games, auctions, etc. Hence, we need a way to approve other addresses to spend our tokens. Let's say you have tether
contract and you want a DEX(Decentralized Exchange) or any other entity transfer coins from the tether
contract. So you keep track of which entity how much can transfer from tether contract in a mapping.
// my address is allowing your address for this much token
mapping(address=>mapping(address=>uint)) public allowance;
In the ERC20 standard, we have a global variable allowed
in which we keep the mapping from an "owner's address" to an "approved spender’s" address and then to the amount of tokens. Calling approve()
function can add an approval to its desired _spender
and _value
. The amount of token is not checked here and it will be checked in transfer().
Once the approval is granted, the "approved spender" can use transferFrom()
to transfer tokens. _from
is the owner address and _to
is the receiver’s address and _value
is the required number of tokens to be sent. First, we check if the owner actually possesses the required number of tokens.
Let's say you want to deposit some ether to a DEFI platform. Interacting with a DEFI platform is actually interacting with the smart contract of that platform. Before you deposit money, you first approve
the transaction. You are telling that this contract address can take some money from my account. Then you call the deposit
function of DEFI smart contract and deposit the money. This how transfer occurs in order:
1- Inside Defi, defi contract has deposit
to get coin from tether
function depositTokens(uint _amount) public{
require(_amount>0,'amount cannot be zero');
// transfer tether to this contract address for staking
tether.transferFrom(msg.sender,address(this), _amount);
// update the state inside Defi, like staked tokens, amount etc
}
2- Inside tether
we have transferFrom
mapping(address=>mapping(address=>uint)) public allowance;
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
// check the allowance
require(_value <=allowance[_from][msg.sender]);
balanceOf[_to]+=_value;
balanceOf[_from]-=_value;
allowance[_from][msg.sender]-=_value;
emit Transfer(_from,_to,_value);
return true;
}
The first requirement is checking the allowance. mapping(address=>mapping(address=>uint)) public allowance
. So actually before calling this, tether
contract has to update its allowance
mapping so this transferFrom
will run smoothly
3- Update the allowance with approve
:
function approve(address _spender, uint _value)public returns (bool success){
allowance[msg.sender][_spender]=_value;
// This event must trigger when a successful call is made to the approve function.
emit Approval(msg.sender,_spender,_value);
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With