Solidity Guide – Accessing and Storing a Struct from External Contract in Solidity

errorsoliditystoragestruct

I was trying to access and store a Struct from an external contract. Is there a way with which this is possible. This would be a simple PoC where I am trying to access a Struct from Student contract in ClassRoom Contract but keep getting:

TypeError: Type tuple(string memory,uint256,bool) is not implicitly convertible to expected type struct stu storage ref.
  --> contracts/TestContract.sol:32:16:
   |
32 |         test = student.studentNames(ID);
   |     

Contracts:

SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
struct stu {
    string name;
    uint age;
    bool tookTest;
}
contract Student{
    mapping(uint => stu) public studentNames;
    function addStudent (uint ID, string memory _name, uint _age) public {
        studentNames[ID] = stu(_name, _age, false);
    }
    function updateStudent (uint ID) public {
        studentNames[ID].tookTest = true;
    }
}
contract ClassRoom {
    address studentAddr;
    Student student;
    stu public test;
    function classRoom(address addr) public {
        studentAddr = addr;
        student = Student(addr);
    }

    //some function that performs a check on student obj and updates the tookTest status to true
    function updateTookTest (uint ID) public {
        student.updateStudent(ID);
    }
    //if you want to access the public mapping
    function readStudentStruct (uint ID) public {
        test = student.studentNames(ID);
    }
}

I can see the call resolves correctly so it's not an issue accessing the mapping and the struct, just storing it. Any ideas?

Best Answer

The issue is that structures are tuples, so you must read them as tuples. The following code will works.

contract ClassRoom{

Student studentContract;
stu public test;

constructor(address _addr) {
    studentContract = Student(_addr);
}

function updateTookTest (uint ID) public {
}

function readStudentStruct (uint ID) public view returns(string memory, 
uint, bool) {

    stu memory student;
    (student.name, student.age, student.tookTest) = 
    studentContract.studentNames(ID);
    return (student.name, student.age, student.tookTest);
}
}
Related Topic