[Ethereum] Compile contracts that call each other

contract-designcontract-developmentgo-ethereumremixsolidity

I have two contracts, one is a Admin, other is subject. To keep things simple I am just including the functions that are invoked in the contracts relating to each other.

contract Subject {
  uint public count = 0;

  function increaseCount() returns newCount{
    count ++;
    newCount = count;
  }
}

The subject contract has a counter that can be increased via a direct call from web3.js or from Master contract.

contract Master {
  bool public isActive=false;
  uint public num=0;

  function changeState() returns bool newState{
    isActive = !isActive;
    newState = isActive;
  }

  function increaseSubjectCount(subjectAddr) returns uint newCount{
    SubjectContract subjectContract = SubjectContract(subjectAddr);
    newCount = ubjectAddr.increaseCount();
  }
}

so a transaction is fired to Master contract (once it is made of course) along with sufficient amount of gas. This function then uses the gas to call increaseCount() function in the Subject contract which returns the new counter. This in turn gets returned by the Master contract via web3.js. The issue I face is if I use browser solidity to compile the Master contract, it throws an error saying SubjectContract parametre undefined. If I add both contracts and then compile the code, when I use

var myContract = web3.eth.contract(masterContract.abi);
won't this cause issues if the abi code includes that of subject and master contract together, but if I don't do this, compiler throws bunch of errors.

Another thing I have considered is using import statements before compilation, but not sure how to safely implement it. Please help out guys!

Best Answer

What you need to do is to define the interface of the SubjectContract contract so that the Master contract can compile.

Here is your Master contract with the SubjectContract interface, along with a few minor changes:

pragma solidity ^0.4.2;

contract SubjectContract {
    function increaseCount() returns (uint newCount);
}

contract Master {
    bool public isActive=false;
    uint public num=0;

    function changeState() returns (bool newState) {
        isActive = !isActive;
        newState = isActive;
    }

    function increaseSubjectCount(address subjectAddr) returns (uint newCount) {
        SubjectContract subjectContract = SubjectContract(subjectAddr);
        newCount = subjectContract.increaseCount();
    }
}

Separately you will have to deploy the following SubjectContract with a few minor changes:

pragma solidity ^0.4.2;

contract SubjectContract {
    uint public count = 0;

    function increaseCount() returns (uint newCount) {
        count ++;
        newCount = count;
    }
}