0

I am desperately trying to manage an array of contracts from a parent contract. Going back to basics, I have implemented the code coming from Pushing a contract to an array in another contract witch roughly does what I want.

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.14;

contract Dog {
  string public name;
  constructor(string memory _name){
       name = _name;
   }
}

contract Human {
  Dog[] public dogs;
  uint public currDogs;

  function addDog() public {
    dogs.push(new Dog("test"));
    currDogs++;
  }
}

Compilation using solc: solc Human.sol --bin --abi -o . --overwrite

Deployment using a JS script similar to the one described in the doc: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#deploy

Going to the JavaScript console, I do the following:

> var abi = [{"inputs":[],"name":"addDog","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currDogs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dogs","outputs":[{"internalType":"contract Dog","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
undefined
> var cnt = web3.eth.contract(abi);
undefined
> 
> var cntinst = cnt.at('0x43d0A1BAC182803587ae9bFF6a4EbF27f3600900');
undefined
> cntinst.addDog({from: eth.accounts[0], gas:3000000});
"0xf9426240a47cb6d0f6f58b47f8b54206bcd665079a6a421f088d41c40b22b5f4"
> cntinst.dogs.length.valueOf()
0
> cntinst.dogs.length
0
> cntinst.dogs[0].name
TypeError: Cannot read property 'name' of undefined
        at <eval>:1:1(4)

The question is: Why is my array "dogs" always empty?

1
  • Where are you executing the code? Perhaps, from the geth console? Geth's console uses an web3 v0.20. In that case you have to use cntinst.dogs(index). For web3 version 1.xx and above cntinst.dogs doesn't exists, it was replaced by cntinst.methods.dogs(index).
    – Ismael
    Commented Jun 4, 2023 at 4:56

1 Answer 1

1

Every time you call function addDog in your Human contract it will always deploy new contract of Dog in blockchain and return its address and push it into dogs array, to understand it better I modified your contract little bit so you can check it.

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.14;

contract Dog {
  string public name;
  constructor(string memory _name){
       name = _name;
   }

   function getName() public view returns(string memory) {
       return name;
   }

}

interface Dogs {
    function getName() external view returns(string memory);
}

contract Human {
  Dog[] public dogs;
  uint public currDogs;

  function addDog(string memory _name) public {
    dogs.push(new Dog(_name));
    currDogs++;
  }

  function getName(uint index) public view returns(string memory) {
      address indexAddress = address(dogs[index]);
      return Dogs(indexAddress).getName();
  }
}
  • Call addDog function with dog name and it will deploy new contract and store address of new contract into the dogs array.
  • Check the length of currDogs.
  • To verify the address call dogs varible and pass the currDogs value - 1 so it would be 0, and you will get contract address.
  • To verify the name you can use two methods .
  1. would be directly call the getName function and pass the value of 0 in it. you will get same name as you used during calling addDog function.
  2. would be using remix at Address feature
  • enter image description here
  • In above image select your Dog contract and use the address you got from dogs variable call and call the method getName
1
  • Following the doc (docs.soliditylang.org/en/latest/abi-spec.html) The Contract Application Binary Interface (ABI) is the standard way to interact with contracts in the Ethereum ecosystem, both from outside the blockchain and for contract-to-contract interaction. If I am not wrong, it does mean that I have to provide at some point the ABI of Dog so that Human is able to interact wit Dog contract. Question is how?
    – eric
    Commented Jun 7, 2023 at 15:46

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.