0

I'm trying to inherit a function from the parent contract into child contract and its working fine in remix JavaScript VM. I did the following steps:

  1. Deployed the parent contract in remix JavaScript VM.
  2. stored some random values by executing the storeValue function from the parent contract
  3. copied the address of the parent contract and instantiated it in child contract Now if I call the getValue function from the child contract that is basically calling the getting stored value function from the parent contract, the output is an array of values and everything is working perfectly fine.


BUT

If I deploy both contracts on the private blockchain, I'm getting an empty array of values. I did following steps:

  1. started the private blockchain (geth client)
  2. Change the environment to Web3 Provider in the remix
  3. deploy the WEB3DEPLOY code from remix in private chain and copied the address of mined address from the private chain
  4. used the address to instantiate the parent contract in child contract
  5. repeated the process of deployment for the child contract
  6. feed the values using web3.py in python jupyter notebook


Now, if I directly call the function accountTx from parent contract in the frontend, its working fine. But, if I call the inherited function getValue from the child contract in the frontend, the result is an empty array.
So, the problem is that I'm unable to get the output of the function getValue that is calling the function from another contract when deployed on a private chain. But its working fine in remix JavaScript VM.
Parent contract:

pragma solidity ^0.4.20;

contract Parent {

    uint256[] values;
    mapping (address => uint256[])transactions;


    function storeValue(uint256 _value) {

        transactions[msg.sender].push(_value);
    }

    function accountTx(address addr) constant returns(uint256[]) {

        return (transactions[addr]);
    }

}


Child contract:

pragma solidity ^0.4.20;

import './Parent.sol';


contract Child {

  /* instantiating parent contract*/
  Parent p = Parent(0x9dd1e8169e76a9226b07ab9f85cc20a5e1ed44dd);


   function getValue() public view returns (uint256[]){
      return p.accountTx(msg.sender);
  }

}

I have created the instance of parent contract as a global because I do want to use it for some functions.
Am missing something like to declare the function as an external? Any guidance would definitely be appreciated, thanks.

1 Answer 1

1

I suspect maybe you misunderstand the inheritance of "the contract".

There are two different ideas that look similar. Let's consider them:

  1. There is a contract A and a contract B and they need to communicate. A is not B and B is not A, but A needs enough information about B in order to communicate with it, and the reverse.
  2. There is a re-usable piece of code that deals with a low-level concern. It will be handy to import it into many contracts so they can "inherit" the logic.

Those are two completely separate concerns.

You might make a re-usable piece of code (deliberately incomplete to keep things on point):

Stoppable.sol

contract Stoppable {

    bool public isRunning;

    modifier onlyIfRunning {
        require(isRunning);
        _;
    }

    function Stoppable() public {
        isRunning = true;
    }

    function setRunSwitch(bool newSetting) public returns(bool contractRunning) {
        isRunning = newSetting;
    }
}

Great. Now if we want A or B to be stoppable, we just go contract A is Stoppable {... and add the onlyIfRunning modifier to the state-changing functions we want to guard. A will get the state variable isRunning as well as the function setRunSwtich() because it inherits the code and its constructor runs whenever an A is deployed.

Now, consider the other case. B wants to inspect something about A, or B wants to send a transaction to A. This is not about inheritance. This is about B have enough information to talk to an instance A.

B needs

  1. The function signatures used by A
  2. The address of an instance of A (where was it deployed?)

A.sol

contract A {

  bytes32 public something;

  function setSomething(bytes32 newThing) public {
    something = newThing;
  }
}

B.sol

contract B {

  A a; // Type A (source available in the contract above), called "a"

  function B(address aAddress) public { // inform B where it can find an instance of A
    a = A(aAddress);
  }

  function getSomethingFromA() public view returns(bytes32 theThing) {
    return a.something();
  }
}

That's not going to compile at first, because A isn't defined. In B.sol you would

import "./A.sol"; 

That's so the compiler can see it and figure out the interface information B needs. Notice that we are not saying anything like B is A.

In case the foregoing is too abstract, consider a system of concert tickets, bands, venues and events, each represented in a set of interlocking contracts. It might be wise to make the contracts inherit a common set of permissions and admin contracts, like the Stoppable idea. Interlocking contracts like Events might inspect Bands and Venues to confirm things make sense, so they will need a little knowledge of interfaces and whereabouts.

It would not seem sensible to say Event is Venue, or Venue is Band. When it starts to get twisted like that, it's a sign of misusing inheritance.

Hope it helps.

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.