5

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!

  • @Varun How did you get the SubjectAddr? I am having trouble to import the contract by SubjectContract subjectContract = SubjectContract(subjectAddr); coz I want to it to get the the address by itself like using Subject.deplyed().address or something like this. – Rajat Mar 10 '17 at 11:04
  • When compiling using browser solidity, you need to place both contracts together. The browser will generate separate byte code so you don't need to worry about it. I didn't understand your question entirely though. As for the subjectAddr, it is a parametre that you need to know before hand and pass it like a regular expression. – Varun Agarwal Mar 10 '17 at 19:28
  • @Varun I meant that because I have both the contracts in the same *.sol file and I have to get subjectAddr for SubjectContract subjectContract = SubjectContract(subjectAddr);. So is there a command which I can use in solidity so that I don't have to insert the contract address in truffle or web3. something like the .address – Rajat Mar 10 '17 at 22:21
  • Not that I know of. You see in my example the point of SubjectContract subjectContract = SubjectContract(subjectAddr); was to reference an existing contract at a known address and inspect its values. So if there are 100 such contracts deployed, I want to be able to call each one separately and inspect its values from Master contract. If the contract address were not to be inserted, it defeats the purpose of my function. :) – Varun Agarwal Mar 11 '17 at 9:36
  • Fair enough! But I still feel that if I have a single solidity file with multiple contracts they should be able to access the basic info such as the address of some other contract in that file. – Rajat Mar 11 '17 at 10:44
6

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;
    }
}
  • Ok so to compile master contract, I would copy paste, what you have written into browser-solidity and compile it. But now when I do let myContract = web3.eth.contract(MasterContract.abi) and execute this, the abi code has the word contract used twice, so how does web3js know I want to create the master contract and subject contract is just an interface? Won't there be confusion regarding this? – Varun Agarwal Dec 29 '16 at 7:59
  • Refer to ethereum.stackexchange.com/questions/7488/… . You will see the there is a separate abiDefinition for TokenCreator and OwnedToken . Your will similarly have separate ABIs for the different contracts. – Bokky WeAreAllAssange PooBah Dec 29 '16 at 18:48
  • Yes, when I compile in solc, I get one abi. But If I have 3 contracts that are inter-dependent on each other, then do I place all three together in browser-solidity and compile it three times such that I get three different abi ? – Varun Agarwal Dec 30 '16 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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