Hi @chim4us,
Sorry for the delay in getting back to you on this.
Are you trying to recreate the code from the video lesson on external contracts from the OLD Ethereum Smart Contract Programming 101 course? Or is this your own extension and experiment with the code from that lesson? Iâm asking, because without seeing your full code from both contracts, itâs difficult to understand what the overall context is. And depending on that, I may need to make different suggestions.
The contract with the external function you are calling (getPerson) is the external contract.
Do you already have the following?
- An interface containing the external function header (in the same file as the contract with the exGetPrs function, or imported);
- Your external contract instance defined as a state variable, using the address of the deployed external contract, and the interface as the data type (in the contract with the exGetPrs function).
Once you have those, you can call your external function within exGetPrs() with:
instance.getPerson()
If getPerson() is the only external function youâre calling from your contract â and youâre not also making an external function call to create a Person instance mapped to the contract address youâre calling from â I can only assume that you want the same addresses, which have already created Person instances in the external contract, to be able to call getPerson() from the other contract to retrieve the data about the person they created. Is that correct? To be able to do that you will have to add an address parameter to getPerson() so that the caller of exGetPrs() has their own address passed to getPerson() and not the contract address. If there is no parameter, then msg.sender in getPerson() refers to the contract address (which hasnât created a Person) and not the caller of exGetPrs() who wants to retrieve the person mapped to their address (not the contract address) in the mapping in the external contract. You can do this like this:
/* getPerson() called from within exGetPrs() */
instance.getPerson(msg.sender)
/* External contract */
function getPerson(address _recordHolder) public view
returns(string memory _name, uint _age, uint _height, bool _senior) {
return(
People[_recordHolder].name, People[_recordHolder].age,
People[_recordHolder].height, People[_recordHolder].senior
);
}
If you want to return all of the data for a person, without manipulating it in any way, then the only code you need to put in your exGetPrs() function body isâŚ
return instance.getPerson(msg.sender);
You canât extract the individual values returned, by using dot notation to append their property names to the function call. Instead, you need to extract them, and assign them to separate local variables, using destructuring assignment, as follows:
(string memory _name, uint _age, uint _height, bool _senior) =
instance.getPerson(msg.sender);
You can then reference each of these local variables separately, by their name, to manipulate them before returning the values you want to return.
If you donât want to extract all of the returned values, or if you just want to exact one of them, then you can omit the declarations of the local variables you donât need, but leave the commas, so that both sides of the assignment operator have the same number of components e.g.
(string memory _name,,,) = instance.getPerson(msg.sender);
return _name;
// or
(string memory _name,, uint _height,) = instance.getPerson(msg.sender);
return (_name, _height);
You can read about this technique and syntax in the documentation:
https://docs.soliditylang.org/en/latest/control-structures.html#destructuring-assignments-and-returning-multiple-values
I really donât understand what it is youâre trying to do with this line of code in exGetPrs()âŚ