3

In my DAPP I have 3 contracts where I want to do something like this.

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

}

In z1, I want to return a z2 contract.

pragma solidity ^0.4.13;

import "./z3.sol";

contract z2 is z3{

    function z2 (){}

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



}

In z2, I want to return a z3 contract.

pragma solidity ^0.4.13;

import "./z1.sol";

contract z3 is z1  {


    function z3 (){}

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


}

In z3, I want to call a function from z1 contract.

I'm trying this on Remix and I get "TypeError: Definition of base has to precede definition of derived contract."

Any idea how can I solve this? Thanks!

2 Answers 2

5

It's just too tangled up to sort it out in a few moves. The main thing seems to be the way you're mixing up interfaces and inheritance. You don't want to use inheritance to merely talk to another contract or even to make another contract from a template.

I took your three concepts and renamed them to "Storage", "Client" and "ClientFactory". Following is a "no frills" way to address all three separate concerns.

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

I used Remix which is great for superficial testing and experimentation.

  1. Deploy a "Storage" and copy the address. Clients will need to know that address to locate it and communicate with it. That is not inheritance. What's happening is Client is compiled to bytecode and while doing so, the compiler can "see" the referenced Storage source code and figure out the function signatures Client will use to talk to it. Since the clients also need to know the actual deployed address (deployed instance of), we'll pass that info to the client's constructor. Copy the Storage contract address to the clipboard for step 3.

  2. Deploy a "ClientFactory".

  3. Using the ClientFactory createClient() function, make it deploy a new Client. The client's constructor expects an address for an instance of Storage (from step 1). Pass it into the function (in quotes). The factory just trusts it's true and blindly passes it along. The new Client contract address is logged so you can see it immediately.

  4. Scroll up to the Client contract. As far as Remix is concerned, no "Client" has never been deployed. Use the AT button to paste in the deployed contract address you got from step 3 (no quotes). You're basically saying, "You know what the interface should look like. You'll find an instance at this address."

  5. Play around with the set/get functions in the Client. They are relying on the storage contract for persistence.

Hope it helps.

0

Delete all files in the build\contracts folder. That fixed the error for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.