Por qué los tokens estándar crean captadores manualmente para balanceOf y totalSupply [duplicado]

He estado leyendo diferentes implementaciones de tokens ERC20 y noté que muchos de ellos definen balanceOf[address] como balances[address] y luego crean un getter() público para que coincida con el estándar balanceOf(). De manera similar, totalSupply generalmente se almacena localmente con un nombre diferente y luego se crea un getter para que coincida con el estándar totalSupply() https://theethereum.wiki/w/index.php/ERC20_Token_Standard

Me preguntaba cuál es el propósito de crear captadores manualmente para estas dos variables. Solidity crea captadores automáticamente para las variables públicas, así que, ¿por qué no darles el nombre correcto para empezar?

Respuestas (1)

No puede implementar la interfaz.

Aunque esta es una pregunta duplicada, no estoy seguro de que las otras respuestas expliquen adecuadamente el problema.

El problema es fácilmente demostrable con un ejemplo simple:

Ejemplo:

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);
    }
}

Si intenta compilar este contrato, terminará con un error como:

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);
    ^-------------------------------------------------------^

El motivo es que, aunque obtiene algunos captadores virtuales y actúa como un token ERC20, no implementa las funciones, por lo que no puede tratarse como un token ERC20 desde la perspectiva del compilador.

Si elimina el is ERC20del contrato o agrega la función deseada manualmente, funciona completamente como se esperaba, simplemente no puede tener la sensación cálida y confusa de que tiene la garantía de haber implementado la interfaz correctamente y minimizar el código al mismo tiempo. .

Creo que esto probablemente podría ser un error del compilador o algo así.

Extraño. ¿Entonces el contrato se vuelve abstracto porque no implementa balanceOf()? Entonces, ¿los captadores públicos que se crean automáticamente a partir de variables son diferentes bajo el capó de los captadores de funciones reales?
O eso o el momento en el que el compilador está comprobando la presencia de las funciones, las funciones captadoras virtuales aún no se han creado.
Oh buen punto. Si ese es el caso, parece que se trata de un error, ya que es un poco redundante crear una función getter cuando ya se ha generado una.
De hecho, he decidido no ser perezoso y he creado un informe de error aquí: github.com/ethereum/solidity/issues/3841
De acuerdo. Creo que podría estar relacionado con este también. github.com/ethereum/solidity/issues/3514
Ta por eso. He cerrado como duplicado. Por ahora es bastante fácil simplemente crear las funciones que el captador virtual haría de todos modos, además obtienes la ventaja de nombrar las variables de entrada en la ABI, por lo que ya no es balanceOf(address) -> uint, esbalanceOf(address to) -> uint value