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

Я здесь новичок и использую openzeppelin framework 2.2.0. При компиляции с Solidity 0.5.8 ошибок не возникло. Но когда я собираюсь развернуть контракт, у меня нет байт-кода и я не могу взаимодействовать с контрактом «Этот контракт не реализует все функции и, следовательно, не может быть создан».

contract SampleCrowdsale is ERC20Detailed, Ownable, FinalizableCrowdsale, TokenTimelock {
    constructor () public ERC20Detailed("SampleCrowdsale", "SCRT", 15) {

    }

    mapping (address => uint256) private balances;

    uint256 public totalSupply = 1000000000000000000000000; 
    uint256 public constant TOKENS_SALE_HARD_CAP = 650000000000000000000000;
    uint256 public constant BASE_RATE = 32500000;

    uint64 private constant dateHOTSale = 1517961600;
    uint64 private constant dateSaleA = 1557991800 - 7 hours;
    uint64 private constant dateSaleB = 1557993600 - 7 hours;
    uint64 private constant dateSaleC = 1557995400 - 7 hours;
    uint64 private constant dateSaleD = 1557999000 - 7 hours;
    uint64 private constant date17May2019 = 1557999180 - 7 hours;

    uint256[4] private roundCaps = [
        100000000000000000000000, 
        250000000000000000000000,
        450000000000000000000000, 
        650000000000000000000000 
    ];
    uint8[4] private roundDiscountPercentages = [50, 25, 12, 6];

    uint64 private constant dateTeamTokensLockedTill = 1557999360 - 7 hours;

    bool public _finalized = false;

    address public timelockContractAddress;

    modifier inProgress {
        require(totalSupply < TOKENS_SALE_HARD_CAP && !_finalized && now >= dateHOTSale);
        _;
    }

    modifier beforeEnd {
        require(!_finalized);
        _;
    }

    function sampleCrowdSale() public {
        }

    modifier tradingOpen {
        require(_finalized);
        _;
    }

    function () external payable {
        purchaseTokens(msg.sender);
    }

    function purchaseTokens(address _beneficiary) public payable inProgress {
        require(msg.value >= 0.05 ether);
        uint256 tokens = computeTokenAmount(msg.value);
        require(totalSupply.add(tokens) <= TOKENS_SALE_HARD_CAP);
        doIssueTokens(_beneficiary, tokens);
        address(0).transfer(address(this).balance);
    }

    function issueTokens(address _beneficiary, uint256 _tokens) public onlyOwner beforeEnd {
        doIssueTokens(_beneficiary, _tokens);
    }

    function doIssueTokens(address _beneficiary, uint256 _tokens) internal {
        require(_beneficiary != address(0));

        totalSupply = totalSupply.add(_tokens);
        balances[_beneficiary] = balances[_beneficiary].add(_tokens);

        emit Transfer(address(0), _beneficiary, _tokens);
    }

    function price() public view returns (uint256 tokens) {
        return computeTokenAmount(1 ether);
    }

    function computeTokenAmount(uint256 ethAmount) internal view returns (uint256 tokens) {
        uint256 tokenBase = (ethAmount.mul(BASE_RATE)/10000000000000)*10000000000;//18 decimals to 15 decimals, set precision to 5 decimals
        uint8 roundNum = currentRoundIndex();
        tokens = tokenBase.mul(100)/(100 - (roundDiscountPercentages[roundNum]));
        while(tokens.add(totalSupply) > roundCaps[roundNum] && roundNum < 4){
           roundNum++;
           tokens = tokenBase.mul(100)/(100 - (roundDiscountPercentages[roundNum]));
        }
    }

    function currentRoundIndex() internal view returns (uint8 roundNum) {
        roundNum = currentRoundIndexByDate();

        while(roundNum < 4 && totalSupply > roundCaps[roundNum]) {
            roundNum++;
        }
    }

    function currentRoundIndexByDate() internal view returns (uint8 roundNum) {
        require(now <= date17May2019);
        if(now > dateSaleD) return 4;
        if(now > dateSaleC) return 3;
        if(now > dateSaleB) return 2;
        if(now > dateSaleA) return 1;
        else return 0;
    }

    function finalize() public onlyOwner beforeEnd {
        uint256 lockedTokens = 230000000000000000000000;
        uint256 partnerTokens = 260000000000000000000000;

        issueLockedTokens(lockedTokens);
        issuePartnerTokens(partnerTokens);

        totalSupply = totalSupply.add(lockedTokens+partnerTokens);

        _finalized = true;

        address(0).transfer(address(this).balance);
    }

    function issueLockedTokens(uint lockedTokens) internal {
        TokenTimelock lockedTeamTokens = new TokenTimelock(this, address(0), dateTeamTokensLockedTill);
        timelockContractAddress = address(lockedTeamTokens);
        balances[timelockContractAddress] = balances[timelockContractAddress].add(lockedTokens);
        emit Transfer(address(0), timelockContractAddress, lockedTokens);
    }

    function issuePartnerTokens(uint partnerTokens) internal{
        balances[address(0)] = partnerTokens;
        emit Transfer(address(0), address(0), partnerTokens);
    }

    function transferFrom(address _from, address _to, uint256 _value) public tradingOpen returns (bool) {
        return transferFrom(_from, _to, _value);
    }

    function transfer(address _to, uint256 _value) public tradingOpen returns (bool) {
        return transfer(_to, _value);
    }
}

Ответы (2)

Если вы развертываете контракт из Remix IDE, вы должны выбрать SampleCrowdsale на вкладке «Выполнение».

Ремикс IDE

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

Сообщение означает то, что оно говорит.

Это не лучший проект для изучения, учитывая объем и сложность кода, с которым вы работаете. Я надеюсь, что это только для практики, и вы не собираетесь соблазнять других вкладывать свои средства в руки кода, который вы не совсем понимаете.

Это много кода для изучения, поэтому я объясню, что вам следует искать.

Когда контракт наследует неопределенные функции от другого контракта, он обязуется обеспечить реализацию функции. Контракт с неопределенными функциями будет скомпилирован, но не может быть развернут. Это связано с тем, что контракт с функцией, которая не знает, что делать, не имеет смысла в цепочке.

Изучите этот небольшой пример в Remix.

pragma solidity 0.5.1;

contract Interface {
    function something() public;
    function somethingElse() public;
}

// does not implement all functions
contract Undeployable is Interface {
    uint x;
    function something() public {
        // do something
        x=1;
    }
}

contract Deployable is Undeployable {
    uint y;
    function somethingElse() public {
        // do something
        y=1;
    }
}

Содержимое функции — это просто заглушки, не имеющие значения. Граф наследования начинается с обязательства реализовать две неопределенные функции. Одна из этих функций определяется Undeployableи подбирается следующим контрактом Deployable, который реализует отсутствующую функцию и наследует something(). Это выполняет обязательства, которые начинаются с наследования Interface. Deployableесть Interface, если это не ясно.

Итак, вы ищете что-то, возможно, в интерфейсе, что не реализовано. Это система безопасности в любом случае. В вашем контракте не будет интерфейса, совместимого с ERC20, пока не будут реализованы все функции, определенные в спецификации. Эта остановка безопасности является целью структурирования кода с контрактом интерфейса, который описывает необходимые функции. Выявление отсутствующей функции может занять немного времени, но это то, что вам нужно точно определить.

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