Search code examples
blockchainethereumsoliditysmartcontracts

How to read arrays of struct from another deployed contract?


OK i have struct array in one already deployed smart contract on mainnet.Now i need to read that array in my contract.I have address of deployed smart contract.I am trying to use it with interface. Something like this:

   pragma solidity ^0.8.7;

interface IContract1{
    struct UserInfo{
   uint id ;
   string ime;
}
    function arr(uint index) external returns(UserInfo memory );
}
contract Contract2{

struct UserInfo{
   uint id ;
   string ime;
}
event UserEVENT (UserInfo UserInfo);
UserInfo [] public newarr;

function foo(address addr,uint i) external {
    IContract1(addr).arr(i);
    emit UserEVENT (IContract1(addr).arr(i));
}
}

This is my caller contract. Of course this is oversimplified example. When i try to put IContract1(addr).arr(i); in emit or try to return UserInfo in foo function compiler throwing me an error TypeError: Invalid type for argument in function call. Invalid implicit conversion from struct IContract1.UserInfo memory to struct Contract2.UserInfo memory requested.

and sc with arr

    pragma solidity ^0.8.7;

contract Contract1{
struct UserInfo{
   uint id ;
   string ime;
}
  
UserInfo [5] public arr;

constructor()  {
    arr[0] = UserInfo(1,"Milos");
   arr[1] = UserInfo(2,"Stefan");
   arr[2] = UserInfo(3,"Sloba");
   arr[3] = UserInfo(4,"Prci");
    arr[4] = UserInfo(5,"Dovla");
}
}

Solution

  • The easiest fix is defining the struct outside both the contract and interface, this way you write it only once and there's no collision.

    This compiles for me:

    pragma solidity ^0.8.7;
    
    struct UserInfo{
       uint id ;
       string ime;
    }
    
    interface IContract1{    
        function arr(uint index) external returns(UserInfo memory );
    }
    
    contract Contract2{
        event UserEVENT (UserInfo UserInfo);
        UserInfo [] public newarr;
    
        function foo(address addr,uint i) external {
            IContract1(addr).arr(i);
            emit UserEVENT (IContract1(addr).arr(i));
        }
    }