[Ethereum] TypeError: Indexed expression has to be a type, mapping or array (is function (address) view external returns (string memory,string memory…)

accessarrayscontract-deploymentmappingsolidity

I have 2 contracts first one is sub second one is main .
First i deploy main and create a new subtoken.
Then I want to access my maincontract in subToken contract but I cant 🙁
When I compile this contract I saw this error at getName2 function :

browser/opz4.sol:17:16: TypeError: Indexed expression has to be a type, mapping or array (is function (address) view external returns
(string memory,string memory,uint8,uint256,uint256)) return
mc.tokens[address(this)].name; ^——-^

pragma solidity ^0.5.0; 
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol'; 

contract SubToken{ 
    MainContract mc;

    constructor(address _address) public{  
       mc=MainContract(_address);

    }  

    function getName1() view public returns(string memory){
        return mc.getNameMain(address(this));
    }

    function getName2() view public returns(string memory){
        return mc.tokens[address(this)].name;
    }

    //function transferFrom(address from, address to, uint tokens) public returns (bool success); 
    //function allowance(address tokenOwner, address spender) public view returns (uint remaining);  
    //function transfer(address to, uint tokens) public returns (bool success) ;  
    //function approve(address spender, uint tokens) public returns (bool success);  
    //function transferFrom(address from, address to, uint tokens) public returns (bool success);  

    event Transfer(address indexed from, address indexed to, uint tokens); 
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens); 

} 
contract MainContract {
    //mapping(address => mapping(address=>uint)) balances;

    //mapping(address => mapping(address => uint)) allowed;

    address[] public contracts;

    using SafeMath for uint;

    address contract_address;

    struct token{ 
        string  name; 
        string   symbol; 
        uint8  decimals; 
        uint  totalSupply; 
        uint balances;
    } 
    mapping(address => token) public tokens;

    address mycontraddress;

    function createNewContract(string memory _name,string memory _symbol,uint8 _decimals,uint256 _totalSupply,uint _balance) public returns(address youraddress){ 
        SubToken st = new SubToken(address(this));//address(this)
        tokens[address(st)] = token(_name,_symbol,_decimals,_totalSupply,_balance);
        mycontraddress=address(st);
        return mycontraddress;
    } 
    function seeContracttAddress() public view returns(address){
        return mycontraddress;
    }

    function getNameMain(address _address) public view returns(string memory){
        return tokens[_address].name;
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

}

anyone can help me please 🙂

Best Answer

I think this behavior is due to the fact that you're passing struct between contract. As you might know they should be passed internally. That said you need to use getNameMain

Here you'll find a similar discussion copy a struct from Contract A into a struct in Contract B using Contract C

Related Topic