[Ethereum] Initialization of object in storage(inside contract ) vs Initialization of object in memory(inside function)

contract-designcontract-developmentsolidity

I am creating an object of another contract in my contract, if I create the object outside any function(global)it works fine but if I create it in any function or constructor the methods of that contract are not accessible, I cant understand why this happens.

following is the working code

This is my storage contract

contract Storage{
    uint id;
    uint status;

    function setId(uint mid){
        id=mid;
    }
    function setStatus(uint mStatus){
        status=mStatus;
    }

}

I am accessing it in to my logic contract, I need multiple objects of this storage contract to storage data with different ids, so that I am mapping the objects with ids.

import './Storage.sol';
contract A{

    mapping (uint=>Storage) idToStorage;
    Storage storage=new Storage();

    function addNewB(uint id){
         idToStorage[id]=storage;
    }
    function getStatus(uint id){
         idToStorage[id].status();
    }

}

This works fine but the issue is object of Storage contract is created globally, and whenever I put object into mapping(ie.idToStorage) the object is pointing to same address, when I change the state of object for any Id that was reflected to the objects for all the Ids,

to over come this I have created the local objects of the Storage contract as in following code

import './Storage.sol';
contract A{

    mapping (uint=>Storage) idToStorage;

    function addNewB(uint id){
         Storage storage=new Storage();
         idToStorage[id]=storage;
    }

    function getStatus(uint id){
         idToStorage[id].status();
    }
}

by this method the issue of same address was resolved, and every object has different address but now the issue is I am not able to access the methods of Storage contract, whenever I tried to access the methods It returns

error: Invalid opcode

can anyone explain, How to handle this case??

Best Answer

Suggest you avoid calling your instance storage because that's a reserved word.

Define your Type and reserve space in the state section, then set the value in the constructor.

contract Storage{
  uint public id;
  uint public status;

  function setId(uint mid) public returns(bool success) {
    id=mid;
    return true;
  }

  function setStatus(uint mStatus) public returns(bool success) {
    status=mStatus;
    return true;
  }
}

// import './Storage.sol';
contract A{

  Storage s; // this defines the type and reserves space

  function A() {
    s = new Storage(); // instantiate it
  }

  function setId(uint id) public returns(bool success) {
     return s.setId(id);
  }

  function setStatus(uint mStatus) public returns(bool success) {
     return s.setStatus(mStatus);
  }

  function getId() public constant returns(uint id) {
     return s.id();
  }
  function getStatus() public constant returns(uint status) {
     return s.status();
  }
}

I removed your mapping because that's another issue and it's not doing anything in this overall structure using simple state variables in the Storage contract.

One or more of these patterns might help you out. Are there well-solved and simple storage patterns for Solidity?

Hope it helps.

Related Topic