Этот контракт не реализует все функции и поэтому не может быть создан

Я следовал руководству, найденному здесь: https://steemit.com/ethereum/@maxnachamkin/how-to-create-your-own-ethereum-token-in-an-hour-erc20-verified .

Я попытался создать этот контракт с помощью Remix. Мне пришлось внести некоторые изменения в код, размещенный на сайте, потому что он устарел. Мне пришлось изменить throw на revert() и изменить sha3() на keccak256().

Ремикс не создаст контракт. В нем говорится: «Этот контракт не реализует все функции и, следовательно, не может быть создан».

Что я делаю неправильно? Любая помощь очень ценится.

прочность прагмы ^0,4,4;

токен контракта {
    функция totalSupply() возвращает константу public (uint totalSupply);
    функция balanceOf(адрес _владелец) константа публичная возвращает (не баланс);
    публичная передача функции (адрес _to, uint _value) (логический успех);
    функция transferFrom(address _from, address _to, uint _value) public возвращает (логический успех);
    функция одобряет (адрес _spender, uint _value) public возвращает (логический успех);
    функция разрешения (адрес _owner, адрес _spender) постоянный публичный возврат (не осталось);
    передача события (адрес с индексом _from, адрес с индексом _to, uint _value);
    Утверждение события (адрес с индексом _owner, адрес с индексом _spender, uint _value);
}



контракт StandardToken является токеном {

    передача функции (адрес _to, uint256 _value) public возвращает (логический успех) {
        // По умолчанию предполагается, что totalSupply не может превышать max (2^256 - 1).
        //Если ваш токен не содержит totalSupply и может выдавать больше токенов с течением времени, вам нужно проверить, не переносится ли он.
        // Вместо этого замените if этим.
        //если (балансы[msg.sender] >= _value && балансы[_to] + _value > балансы[_to]) {
        если (балансы [msg.sender] >= _value && _value > 0) {
            балансы[msg.sender] -= _value;
            балансы[_to] += _value;
            Transfer(msg.sender, _to, _value);
            вернуть истину;
        } иначе { вернуть ложь; }
    }

    function transferFrom(address _from, address _to, uint256 _value) public возвращает (логический успех) {
        //то же, что и выше. Замените эту строку следующей, если вы хотите защититься от переноса uint.
        //if (балансы[_from] >= _value && разрешённые[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
        if (балансы[_from] >= _value && разрешено[_from][msg.sender] >= _value && _value > 0) {
            балансы[_to] += _value;
            балансы[_от] -= _значение;
            разрешено[_from][msg.sender] -= _value;
            Перевод(_от, _до, _значение);
            вернуть истину;
        } иначе { вернуть ложь; }
    }

    функция balanceOf(адрес _owner) константа общедоступная возвращает (баланс uint256) {
        возврат остатков[_owner];
    }

    функция одобряет (адрес _spender, uint256 _value) public возвращает (логический успех) {
        разрешено[msg.sender][_spender] = _value;
        Утверждение (msg.sender, _spender, _value);
        вернуть истину;
    }

    функция допуск (адрес _owner, адрес _spender) постоянный общедоступный возврат (осталось uint256) {
      возврат разрешен[_owner][_spender];
    }

    сопоставление (адрес => uint256) балансов;
    отображение (адрес => отображение (адрес => uint256)) разрешено;
    uint256 публичный общий объем поставок;
}


// назовите этот контракт как хотите
контракт TestToken является StandardToken {

    функция () общедоступная {
        //если эфир отправлен на этот адрес, отправляем его обратно.
        возвращаться();
    }

    /* Публичные переменные токена */

    /*
    ЗАМЕЧАНИЯ:
    Следующие переменные НЕОБЯЗАТЕЛЬНЫ. Их не обязательно включать.
    Они позволяют настраивать контракт токена и никоим образом не влияют на основную функциональность.
    Некоторые кошельки/интерфейсы могут даже не удосужиться просмотреть эту информацию.
    */
    общедоступное имя строки = "TestToken"; //причудливое имя: например, Саймон Бакс
    uint8 общедоступные десятичные знаки = 0; // Сколько десятичных знаков показывать. т.е. Там может быть 1000 базовых единиц с 3 десятичными знаками. Значение 0,980 SBX = 980 базовых единиц. Это как сравнивать 1 вэй с 1 эфиром.
    общедоступный символ строки = "ТТТ"; //Идентификатор: например, SBX
    общедоступная версия строки = "1.0"; //человеческий стандарт 0.1. Просто произвольная схема управления версиями.

//
// ИЗМЕНИТЬ ЭТИ ЗНАЧЕНИЯ ДЛЯ ВАШЕГО ТОКЕНА
//

//убедитесь, что это имя функции совпадает с именем контракта выше. Поэтому, если ваш токен называется TutorialToken, убедитесь, что указанное выше имя //контракта также TutorialToken вместо ERC20Token.

    функция TestToken() общедоступная {
        балансы[msg.sender] = 100000; // Отдаем создателю все начальные токены (например, 100000)
        общее предложение = 100000; // Обновление общего предложения (например, 100000)
        имя = "ТестТокен"; // Задаем имя для отображения
        десятичные знаки = 0; // Количество десятичных знаков для отображения
        символ = "ТТТ"; // Устанавливаем символ для отображения
    }

    /* Утверждает, а затем вызывает принимающий контракт */
    функция appendAndCall (адрес _spender, uint256 _value, байты _extraData) общедоступные результаты (логический успех) {
        разрешено[msg.sender][_spender] = _value;
        Утверждение (msg.sender, _spender, _value);

        // вызовите функцию ReceiveApproval для контракта, который вы хотите уведомить. Это создает сигнатуру функции вручную, поэтому не нужно включать здесь контракт только для этого.
        //receiveApproval(адрес _from, uint256 _value, адрес _tokenContract, байты _extraData)
        // предполагается, что когда это происходит, вызов *должен* завершиться успешно, иначе вместо этого можно было бы использовать ванильное одобрение.
        if(!_spender.call(bytes4(bytes32(keccak256("receiveApproval(адрес,uint256,адрес,байты)"))), msg.sender, _value, this, _extraData)) { revert(); }
        вернуть истину;
    }
}

Ответы (2)

Проблема в том, что totalSupply()реализация отсутствует. Похоже, что автогенерируемые геттеры не в счет. Поэтому вам нужно явно создать функцию.

contract StandardToken is Token {
    uint256 _totalSupply;

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

Согласен с Андреем, потому что totalSupplyон объявлен как часть интерфейса и никогда не определяется. Несоответствие заставило меня быстро проверить прагму, и она не компилируется 0.4.4из-за наличия revert.

Этот

pragma solidity ^0.4.18;

contract Token {
    uint public totalSupply;

плюс это около 59

// uint256 public totalSupply;

потому что это было бы лишним.

Я чувствую, что должен предостеречь вас от того, чтобы идти вперед с чем-то, что исследовано лишь поверхностно. (без гарантии). Рассмотрите возможность использования текущего и хорошо проверенного набора контрактов вместо того, чтобы возиться с тем, в котором есть ошибки. В поисках неочевидных упущений приходится рыться в большом количестве кода.

Надеюсь, это поможет.

Спасибо! Я делал это для получения опыта, а не пытался создать что-то конкретное. Есть ли у вас какие-либо рекомендации по текущему и хорошо проверенному набору контрактов, с которыми можно поиграть, чтобы узнать больше о том, как все это работает?