TypeError: определение базы должно предшествовать определению производного контракта

В моем DAPP у меня есть 3 контракта, где я хочу сделать что-то подобное.

pragma solidity ^0.4.13;

import "./z2.sol";

contract z1 {

    uint example;

    function z1 (){ example = 33;}


    function createZ2() returns(z2){
        z2 newZ2 = new z2();
        return newZ2;
    }

    function getZ1example() returns(uint){
        return example;
    }

}

В z1 хочу вернуть контракт z2.

pragma solidity ^0.4.13;

import "./z3.sol";

contract z2 is z3{

    function z2 (){}

    function createZ3() returns(z3){
        z3 newZ3 = new z3();
        return newZ3;
    }



}

В z2 хочу вернуть контракт z3.

pragma solidity ^0.4.13;

import "./z1.sol";

contract z3 is z1  {


    function z3 (){}

    function getZ3example() returns(uint){
        return (z1.getZ1example());
    }


}

В z3 я хочу вызвать функцию из контракта z1.

Я пробую это на Remix и получаю «TypeError: определение базы должно предшествовать определению производного контракта».

Есть идеи, как я могу это решить? Спасибо!

Ответы (2)

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

Я взял ваши три концепции и переименовал их в «Хранилище», «Клиент» и «Клиентская фабрика». Ниже приведен способ «без излишеств» решить все три отдельные проблемы.

pragma solidity 0.4.13;

contract Storage {

    mapping(uint => bytes32) public byteMap;

    function setStorage(uint key, bytes32 value) public returns(bool success) {
        byteMap[key] = value;
        return true;
    }

    function getStorage(uint key) public constant returns(bytes32 value) {
        return byteMap[key];
    }
}

contract Client {

    Storage datastore;

    function Client(address storageAddress) public {
        datastore = Storage(storageAddress);
    }

    function setValue(uint key, bytes32 value) public returns(bool success) {
        datastore.setStorage(key, value);
        return true;
    }

    function getValue(uint key) public constant returns(bytes32 value) {
        return datastore.getStorage(key);
    }
}

contract ClientFactory {

    event LogNewClientCreated(address sender, address newClient);

    function createClient(address storageContract) public returns(address newClient) {
        Client c = new Client(storageContract);
        LogNewClientCreated(msg.sender, c);
        return c;
    }
}

Я использовал Remix, который отлично подходит для поверхностного тестирования и экспериментов.

  1. Разверните «Хранилище» и скопируйте адрес. Клиентам необходимо знать этот адрес, чтобы найти его и связаться с ним. Это не наследство . Что происходит, так это то, что клиент скомпилирован в байт-код, и при этом компилятор может «увидеть» указанный исходный код хранилища и определить сигнатуры функций, которые клиент будет использовать для общения с ним. Поскольку клиентам также необходимо знать фактический развернутый адрес (развернутый экземпляр), мы передадим эту информацию конструктору клиента. Скопируйте адрес контракта хранилища в буфер обмена для шага 3.

  2. Разверните «ClientFactory».

  3. Используя функцию ClientFactory createClient(), заставьте ее развернуть новый клиент. Конструктор клиента ожидает адрес для экземпляра Storage (из шага 1). Передайте его в функцию (в кавычках). Фабрика просто верит, что это правда, и слепо передает ее. Новый адрес клиентского контракта регистрируется, поэтому вы можете сразу его увидеть.

  4. Прокрутите вверх до клиентского договора. Что касается Remix, то ни один «Клиент» никогда не развертывался. Используйте кнопку AT , чтобы вставить адрес развернутого контракта, который вы получили на шаге 3 (без кавычек). По сути, вы говорите: «Вы знаете, как должен выглядеть интерфейс. Вы найдете экземпляр по этому адресу».

  5. Поэкспериментируйте с функциями set/get в клиенте. Они полагаются на контракт хранения для постоянства.

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

Удалите все файлы в папке build\contracts. Это исправило ошибку для меня.