0

As I am reading about ERC20 standard, I found some points that confused me a bit. Below, you can see the code that I am trying to understand. So, my questions are the following;

  1. It says as a comment in the code "Create a table so that we can map the addresses of contract owners to those who are allowed to utilize the owner's contract". Who are considered in this context "contract owners"? Are the ones that have bought tokens?

  2. I totally get the first mapping mapping(address => uint256) balances; but the second one mapping(address => mapping (address => uint256)) allowed; is not clear to me. What is the purpose of that mapping and why is that useful?

  3. What is the difference between the functions transfer() and transferFrom().

That's it! Thanks

pragma solidity ^0.4.15;



contract MyERCToken

{



 // Create a table so that we can map addresses

 // to the balances associated with them



 mapping(address => uint256) balances;



 // Create a table so that we can map

 // the addresses of contract owners to

 // those who are allowed to utilize the owner's contract



 mapping(address => mapping (address => uint256)) allowed;



 // In this case, the total supply

 // of MyERCToken is fixed, but

 // it can very much be changed

 uint256 _totalSupply = 1000000;

 // Owner of this contract



 address public owner;
 

function totalSupply() constant returns (uint256 theTotalSupply) {



   // Because our function signature

   // states that the returning variable

   // is "theTotalSupply", we'll just set that variable

   // to the value of the instance variable "_totalSupply"

   // and return it



   theTotalSupply = _totalSupply;



   return theTotalSupply;

 }

 

 function balanceOf(address _owner) constant returns (uint256 balance) {

   return balances[_owner];

 }

 

 function approve(address _spender, uint256 _amount) returns (bool success) {

   allowed[msg.sender][_spender] = _amount;

 

 // Fire the event "Approval" to execute any logic

   // that was listening to it



   Approval(msg.sender, _spender, _amount);

   return true;



 }

 

 // Note: This function returns a boolean value

 //       indicating whether the transfer was successful



 function transfer(address _to, uint256 _amount) returns (bool success) {



   // If the sender has sufficient funds to send

   // and the amount is not zero, then send to

   // the given address

 

 if (balances[msg.sender] >= _amount

     && _amount > 0

     && balances[_to] + _amount > balances[_to]) {

     balances[msg.sender] -= _amount;

     balances[_to] += _amount;



     // Fire a transfer event for any

     // logic that's listening



     Transfer(msg.sender, _to, _amount);

       return true;

     } else {

       return false;

     }

  }

  

  function transferFrom(address _from, address _to, uint256 _amount) returns (bool success) {

   if (balances[_from] >= _amount

     && allowed[_from][msg.sender] >= _amount

     && _amount > 0

     && balances[_to] + _amount > balances[_to]) {

   balances[_from] -= _amount;

   balances[_to] += _amount;

   Transfer(_from, _to, _amount);

     return true;

   } else {

     return false;

   }

 }

 

 function allowance(address _owner, address _spender) constant returns (uint256 remaining) {

   return allowed[_owner][_spender];

 }



 // Triggered whenever approve(address _spender, uint256 _value) is called.

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

 // Triggered when tokens are transferred.

event Transfer(address indexed _from, address indexed _to, uint256 _value);

}

2 Answers 2

1

That is a poorly worded comment. It should read:

Create a table so that we can map the addresses of token owners to those who are allowed to utilize the said owner's tokens.

This lets you whitelist someone else to use your tokens. For instance, you can allow me to spend 10 of your tokens. So, with .approve, you save in the mapping:

you => me => 10

Then I go out and spend 7 of them. I cannot call .transfer of course, so I have to use .transferFrom(you, 7). Because of proper accounting in transferFrom, there remains in the mapping:

you => me => 3

Useful. Even more useful if you want to allow another contract to spend on your behalf. For instance, you can put your tokens for sale on a decentralised exchange, and allow this exchange to "spend" 100 of your tokens on your behalf when a possible trade comes along.

It can be used by you to make sure that you send your tokens to the right address too. After all, it is easy to make a mistake on the recipient address of transfer. But if you approve your recipient to take them, and then have the recipient contract take them, then you have better confirmation that it was meant to receive them, and it is a contract that can deal with ERC-20. Not all contracts do.

1
  • 1
    Everything makes sense now. Thanks!
    – John
    Oct 15, 2020 at 12:55
1

I'm not sure where you found that example but there are multiple issues with it:

  1. It's old. That version of Solidity shouldn't be used in new projects anymore

  2. The comments in it do not make sense so just ignore them

  3. It has a bit of weird code

Perhaps the best and most widely-used modern implementation is from OpenZeppelin at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol . It has some extra complexities (such as inheriting from Context) but you can mostly ignore those.

As for your questions: 1) there are no contract owners so just ignore the comment. 2) the allowed is a variable which says how much an address is allowed to withdraw from another token owner's balance. 3) transfer is used for direct token transfers, transferFrom is used in conjunction with approve where the token owner first approves that certain address can take some amount of his tokens and then that other address takes them with transferFrom - such functionality is useful when exchanging tokens.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.