Cannot get state variable of a contract deployed from a factory contract in truffle

contract-deploymentsoliditytruffle

Hello I have 2 smart contracts – Children Factory and Child:

pragma solidity 0.8.6;
import "./Child.sol";

contract ChildrenFactory {
      
      Child[] public children;
      address[] public childrenAddresses;

    event ChildCreated(address newChild);

      function createChild(uint age) public {
         Child child = new Child(age);
         emit ChildCreated(address(child));
         children.push(child);
         childrenAddresses.push(address(child));
      }
}
pragma solidity 0.8.6;

contract Child {
     uint public age;
     address public childAddress;
     
     constructor(uint _age) {
        age = _age;
        childAddress = address(this);
     }

     function getAge() public view returns(uint childAge) {
         childAge = age;
     }
}

I migrated the factory contract in truffle and ran the following code:

let instance = await ChildrenFactory.deployed()
instance.createChild(5) // I got the address of the new child contract from the tx log
let child1 = await Child.at('the address from the tx')
await child1.getAge() // results in an error

both getAge and age() return the following error:

Uncaught Error: Returned error: VM Exception while processing
transaction: revert.

As far as I know, this was supposed to be the right way to interact with contracts deployed from the factory but apparently, it is not and I don't know what I'm doing wrong. I would very much appreciate every help.

Best Answer

Please try the following :

  1. Open the truffle development console at the root of your truffle project with the command truffle develop

  2. Deploy the ChildrenFactory smart contract with truffle migrate --reset

My migration file is :

const ChildrenFactory = artifacts.require("ChildrenFactory");

module.exports = function(deployer) {
deployer.deploy(ChildrenFactory);
};
  1. Get the ChildrenFactory contract instance

    let instance = await ChildrenFactory.deployed()
    
  2. Deploy the Child smart contract

    let tx = await instance.createChild(5) 
    
  3. From the transaction receipt, get the address of the Child contract.

Use tx.logs and see the address given inside the args field (or use tx.logs[0].args[0] to get the address directly).

  1. Get the Child contract instance

    let child1 = await Child.at('the address from the tx receipt')
    
  2. Call the function of the Child contract

    await child1.getAge() 
    

It will return BN { negative: 0, words: [ 5, <1 empty item> ], length: 1, red: null } with the value returned by the smart contract in the words field.

Related Topic