1

I've been reading through different implementations of ERC20 tokens and I noticed that many of them define balanceOf[address] as balances[address] and then create a public getter() to match the balanceOf() standard. Similarly, totalSupply is usually stored locally under a different name and then has a getter created to match the standard totalSupply() https://theethereum.wiki/w/index.php/ERC20_Token_Standard

I was wondering what is the purpose of manually creating getters for these two variables? Solidity automatically creates getters for public variables so why not just name them the proper name to begin with?

marked as duplicate by Eli Drion, cleanunicorn, Community Apr 6 '18 at 15:53

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2

It can't implement the interface

Even though this is a duplicate question, I'm not sure the other answers adequately explain the issue.

The problem is easily demonstable with a simple example:

Example:

pragma solidity ^0.4.21;

interface ERC20 {
    function balanceOf(address) external view returns (uint);
    function transfer(address, uint) external returns (bool);
}

contract TestA is ERC20 {
    mapping(address=>uint) public balanceOf;

    function TestA() public {
        balanceOf[this] = 1000;
    }

    function transfer(address _to, uint256 _value) external returns (bool success){
        require(balanceOf[msg.sender] >= _value);
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        require(balanceOf[_to] >= _value);
        return true;
    }
}

contract TestB {
    address a;

    function TestB() public {
        a = new TestA();
    }

    function aBalance() external view returns (uint) {
        return ERC20(a).balanceOf(a);
    }
}

If you try and compile this contract you will end up with an error like:

browser/contract.sol:28:13: TypeError: Trying to create an instance of an abstract contract.
        a = new TestA();
            ^-------^
browser/contract.sol:4:5: Missing implementation:
    function balanceOf(address) external view returns (uint);
    ^-------------------------------------------------------^

The reason why is that even though it gets some virtual getters, and acts like an ERC20 token, it doesn't implement the functions, so it can't be treated as an ERC20 token from the compiler's perspective.

If you either remove the is ERC20 from the contract, or add the wanted function manually, it works fully as expected, you just can't have the warm fuzzy feeling that you're guaranteed to have implemented the interface correctly and minimise code at the same time.

I believe this could probably be a compiler bug or something actually.

  • Weird. So the contract becomes abstract because it doesn't implement balanceOf()? So the public getters that are automatically created from variables are different under the hood from actual function getters? – arete Apr 6 '18 at 16:13
  • Either that or the point in time at which the compiler is checking for the presence of the functions, the virtual getter functions haven't yet been created. – norganna Apr 6 '18 at 16:17
  • Oh good point. If that is the case it seems like this is a bug, since it's a bit redundant to create a getter function when there is already one generated. – arete Apr 6 '18 at 16:19
  • Actually I've decided to not be lazy and have created a bug report here: github.com/ethereum/solidity/issues/3841 – norganna Apr 6 '18 at 16:31
  • Ok. I think it might be related to this one as well. github.com/ethereum/solidity/issues/3514 – arete Apr 6 '18 at 17:06

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