0

I have a factory contract with the below code:

//SPDX-License-Identifier: no-license
pragma solidity ^0.8.9;

interface ChildInterface {
    function getStateVariable() external returns(uint);
}

contract Child is ChildInterface{
    uint public x;
    address public owner;

    constructor(address _owner, uint _x) {
        x = _x;
        owner = _owner;
    }

    function getStateVariable() public view returns(uint){
        return x;
    }
}

contract Parent {

 Child[] public childContracts;

 function createContract(uint seller) public {
        // - create a new Lottery instance with msg.sender as seller.
        Child newContract = new Child(msg.sender, seller);

        // - push the newly created contract to lotteries array.
        childContracts.push(newContract);
 }

function getValidChildContractAddresses() public returns(bytes memory addresses){
     Child[] memory validChildContracts;
     
     for(uint i = 0;i <= childContracts.length;i++){
         if(ChildInterface(childContracts[i]).getStateVariable() == 10){
              validChildContracts[i] = address(childContracts[i]);
         }          
     }

     addresses = abi.encode(validChildContracts);
 }
}

I am trying to get all the addreses of the child contracts are stored in the childContracts that matches a condition and convert them as bytes to be returned in the getCreatedContractAddresses() function.

I'm getting the error: 'TypeError: Type address is not implicitly convertible to expected type contract Child.' in this line: validChildContracts[i] = address(childContracts[i]);.

May I know how to achieve that?

2
  • Your code looks fine. Are you facing any errors? If so, can you post them?
    – pbsh
    Commented Jan 19, 2022 at 8:48
  • Hi, I updated the code with error and a full code to be run on remix.
    – toddash
    Commented Jan 19, 2022 at 13:56

1 Answer 1

1

The issue is in the following line

Child[] memory validChildContracts;

This created the variable validChildContracts of type Child[]. However, it needs to be of type address[] as we aren't creating an instance of the child, but merely storing its' address.

address[] memory validChildContracts; should fix the error.

6
  • Hi, I actually need to have the Child[] in validChildContracts so that I can use it to change state varialbe by calling methods with in the child contract like: ChildInterface(validChildContracts[i]).childContractMethod(). Is it possible even If I use it as address[] memory validChildContracts?
    – toddash
    Commented Jan 19, 2022 at 15:23
  • I am trying to use this functionality with chainlink's checkupkeep and performupkeep functions. like passing the validChildContracts list of addreses to the performupkeep function and call ChildInterface(validChildContracts[i]).somefunctionInChildContract(). May I know if that will make changes to the state variables deployed contract under the validChildContracts[i] address (where i is a local variable in for loop)?
    – toddash
    Commented Jan 19, 2022 at 15:28
  • 1
    What you explained in ChildInterface(validChildContracts[i]).childContractMethod() is right. Its creating an instance of ChildItnterface at the address validChildContracts[i]. You can then interact with it normally.
    – pbsh
    Commented Jan 19, 2022 at 16:01
  • hi @pbsh, I am getting the following error when I try running getValidChildContractAddresses() in Parent contract: Note: The called function should be payable if you send value and the value you send should be less than your current balance.
    – toddash
    Commented Jan 20, 2022 at 3:53
  • Are you sure it's coming from getValidChildContractAddresses because there isn't any code inside it that's sending ether?
    – pbsh
    Commented Jan 20, 2022 at 5:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.