Este contrato no implementa todas las funciones y, por lo tanto, no se puede crear

Seguí el tutorial que se encuentra aquí: https://steemit.com/ethereum/@maxnachamkin/how-to-create-your-own-ethereum-token-in-an-hour-erc20-verified

Traté de crear este contrato usando Remix. Tuve que hacer algunos cambios en el código publicado en el sitio web porque estaba desactualizado. Tuve que cambiar throw a revert() y cambié sha3() a keccak256().

Remix no creará el contrato. Dice: "Este contrato no implementa todas las funciones y, por lo tanto, no se puede crear".

¿Qué estoy haciendo mal? Cualquier ayuda es muy apreciada.

solidez de pragma ^0.4.4;

ficha de contrato {
    function totalSupply() constante pública devuelve (uint totalSupply);
    function balanceOf(dirección _propietario) rendimientos públicos constantes (saldo uint);
    función de transferencia (dirección _a, uint _valor) devoluciones públicas (bool éxito);
    función transferFrom(dirección _desde, dirección _a, uint _valor) retornos públicos (bool éxito);
    función aprobar (dirección _gastador, uint _valor) devoluciones públicas (bool éxito);
    asignación de funciones (dirección _propietario, dirección _gastador) retornos públicos constantes (uint restante);
    transferencia de eventos (dirección indexada _desde, dirección indexada _a, uint _valor);
    Aprobación del evento (dirección indexada _propietario, dirección indexada _gastador, uint _valor);
}



contrato StandardToken es Token {

    función de transferencia (dirección _a, uint256 _valor) devoluciones públicas (bool éxito) {
        // El valor predeterminado asume que totalSupply no puede superar el máximo (2^256 - 1).
        //Si su token deja fuera totalSupply y puede emitir más tokens a medida que pasa el tiempo, debe verificar si no se ajusta.
        //Reemplace el if con este en su lugar.
        //si (saldos[mensaje.remitente] >= _valor && saldos[_a] + _valor > saldos[_a]) {
        if (saldos[mensaje.remitente] >= _valor && _valor > 0) {
            saldos[mensaje.remitente] -= _valor;
            saldos[_a] += _valor;
            Transferir(mensaje.remitente, _a, _valor);
            devolver verdadero;
        } más { devuelve falso; }
    }

    function transferFrom(dirección _from, dirección _to, uint256 _value) public return (bool éxito) {
        //lo mismo que arriba. Reemplace esta línea con la siguiente si desea protegerse contra las uniones de envoltura.
        //si (saldos[_de] >= _valor && permitido[_de][mensaje.remitente] >= _valor && saldos[_a] + _valor > saldos[_a]) {
        if (saldos[_de] >= _valor && permitido[_de][mensaje.remitente] >= _valor && _valor > 0) {
            saldos[_a] += _valor;
            saldos[_desde] -= _valor;
            permitido[_de][mensaje.remitente] -= _valor;
            Transferir(_desde, _a, _valor);
            devolver verdadero;
        } más { devuelve falso; }
    }

    function balanceOf(dirección _propietario) rendimientos públicos constantes (saldo uint256) {
        devolver saldos[_propietario];
    }

    función aprobar (dirección _gastador, uint256 _valor) devoluciones públicas (bool éxito) {
        permitido[mensaje.remitente][_gastador] = _valor;
        Aprobación (mensaje.remitente, _gastador, _valor);
        devolver verdadero;
    }

    asignación de función (dirección _propietario, dirección _gastador) rendimientos públicos constantes (uint256 restantes) {
      devolución permitida[_propietario][_gastador];
    }

    mapeo (dirección => uint256) saldos;
    mapeo (dirección => mapeo (dirección => uint256)) permitido;
    uint256 suministro total público;
}


//nombra este contrato como quieras
contrato TestToken es StandardToken {

    función () público {
        //si se envía ether a esta dirección, devuélvelo.
        revertir();
    }

    /* Variables publicas del token */

    /*
    NOTA:
    Las siguientes variables son tocadores OPCIONALES. Uno no tiene que incluirlos.
    Permiten personalizar el contrato de token y de ninguna manera influyen en la funcionalidad principal.
    Es posible que algunas billeteras/interfaces ni siquiera se molesten en mirar esta información.
    */
    cadena nombre público = "TestToken"; // nombre elegante: por ejemplo, Simon Bucks
    uint8 decimales públicos = 0; //Cuantos decimales mostrar. es decir. Podría haber 1000 unidades base con 3 decimales. Es decir 0.980 SBX = 980 unidades base. Es como comparar 1 wei con 1 éter.
    cadena símbolo público = "TTT"; //Un identificador: por ejemplo, SBX
    cadena versión pública = "1.0"; //estándar humano 0.1. Solo un esquema de versiones arbitrario.

//
// CAMBIA ESTOS VALORES POR TU TOKEN
//

//asegúrese de que el nombre de esta función coincida con el nombre del contrato anterior. Entonces, si su token se llama TutorialToken, asegúrese de que el //nombre del contrato anterior también sea TutorialToken en lugar de ERC20Token

    función TestToken() público {
        saldos[mensaje.remitente] = 100000; // Dale al creador todos los tokens iniciales (100000 por ejemplo)
        suministro total = 100000; // Actualizar suministro total (100000 por ejemplo)
        nombre = "Ficha de prueba"; // Establecer el nombre para fines de visualización
        decimales = 0; // Cantidad de decimales para fines de visualización
        símbolo = "TTT"; // Establecer el símbolo para fines de visualización
    }

    /* Aprueba y luego llama al contrato receptor */
    función de aprobar y llamar (dirección _gastador, uint256 _valor, bytes _extraData) devoluciones públicas (bool éxito) {
        permitido[mensaje.remitente][_gastador] = _valor;
        Aprobación (mensaje.remitente, _gastador, _valor);

        //llame a la función receiveApproval en el contrato que desea que se le notifique. Esto crea la firma de la función manualmente para que no se tenga que incluir un contrato aquí solo para esto.
        //receiveApproval(dirección _from, uint256 _value, dirección _tokenContract, bytes _extraData)
        //se supone que cuando hace esto, la llamada *debería* tener éxito, de lo contrario, se usaría la aprobación de vainilla en su lugar.
        if(!_spender.call(bytes4(bytes32(keccak256("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { revert(); }
        devolver verdadero;
    }
}

Respuestas (2)

El problema es que totalSupply()falta implementación. Parece que los captadores generados automáticamente no cuentan. Entonces necesitas crear explícitamente la función.

contract StandardToken is Token {
    uint256 _totalSupply;

    function totalSupply() constant returns (uint256 totalSupply) {
        totalSupply = _totalSupply;
    }
}      

De acuerdo con Andrey, es porque totalSupplyse declara como parte de la interfaz y luego nunca se define. La inconsistencia me llevó a verificar el pragma rápidamente, y no se compila 0.4.4debido a la presencia de revert.

Esto

pragma solidity ^0.4.18;

contract Token {
    uint public totalSupply;

más esto cerca de 59

// uint256 public totalSupply;

porque sería redundante.

Siento que debo advertirle sobre seguir adelante con algo que solo se investiga superficialmente. (Sin garantía). Considere usar un conjunto de contratos actualizado y bien revisado en lugar de jugar con uno que tiene errores. Es mucho código para navegar en busca de descuidos no obvios.

Espero eso ayude.

¡Gracias! Estaba haciendo esto por la experiencia de aprendizaje en lugar de tratar de crear algo en particular. ¿Tiene alguna recomendación sobre un conjunto actual y bien revisado de contratos con los que jugar para obtener más información sobre cómo funciona todo esto?