I have 2 separate contracts and I want to reach a single array element in another contract using interface:
contract ContractA {
struct Person {
string name;
}
Person[] public persons;
function createPerson(string memory _name) public {
persons.push(Person(_name));
}
}
interface IContractA {
struct Person {
string name;
}
function persons(uint256 _index) external view returns (Person memory);
}
contract ContractB {
address contractAddress = 0x3328358128832A260C76A4141e19E2A943CD4B6D;
function getPerson(uint256 _index)
public
view
returns (IContractA.Person memory)
{
IContractA contractAIns = IContractA(contractAddress);
return contractAIns.persons(_index);
}
}
but I'm taking this error and I don't think this is related about payable(cuz it's not and also tried):
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
I'm using interface for reach that element and I can reach a number variable with this way, but can't reach a struct element. Is there any way to reach?
Automatic getters are not recognized in interface implementation. you can read this discussion. Automatic getters not recognized in interface implementation. interfaces only define the function signatures, not the implementation. the problem is you have persons
in the interface
function persons(uint256 _index) external view returns (Person memory);
since automatic getters are not recognized, you have to implement it in the contractA
.
To fix it change the persons
to person
in the interface. (because u have a "persons" array in the contractA)
interface IContractA {
struct Person {
string name;
}
function person(uint256 _index) external view returns (Person memory);
}
then add person()
to contractA
contract ContractA {
struct Person {
string name;
}
Person[] public persons;
function createPerson(string memory _name) public {
persons.push(Person(_name));
}
function person(uint _index) external view returns (Person memory) {
return persons[_index];
}
}
finally, in contractB
call contractAIns.person(_index)
contract ContractB {
address contractAddress = 0xD7ACd2a9FD159E69Bb102A1ca21C9a3e3A5F771B;
function getPerson(uint256 _index)
public
view
returns (IContractA.Person memory)
{
IContractA contractAIns = IContractA(contractAddress);
return contractAIns.person(_index);
}
}