0

I have two contracts, one serves as a contract factory (A) for the other (B). When I try to deploy (B), I don't receive an error, but the contract doesn't get deployed.

contract A {

    function CreateB() public returns (address) {
        B b = new B(msg.sender, address(this));
        return address(b);
    }
}

contract B{

    address public parentA;

    address public owner;

    constructor(
        address OwnerOfB,
        address A,
    ) {
        owner = OwnerOfB;
        parentA = A;
    }
}

Here's the deploy function (I use hardhat local chain)

async function main(){
      const A = await ethers.getContractFactory("A");
      const a = await Planter.deploy();
    
      await planted.deployed();

      const B = await a.CreateTree();
      console.log(B);
    }

Here's what I get as the output:

{hash: '0x0438b599c92a0a13bac6eea048aa4275a52684e4e55642ccfbeae9423eef76bc',
  type: 2,
  accessList: [],
  blockHash: '0x9950bec678b71bee5f52cdbfe34967cf72c89b5e0f3ed4ca0b082843a203dda4',
  blockNumber: 2,
  transactionIndex: 0,
  confirmations: 1,
  from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
  gasPrice: BigNumber { value: "1771848095" },
  maxPriorityFeePerGas: BigNumber { value: "1000000000" },
  maxFeePerGas: BigNumber { value: "2543696190" },
  gasLimit: BigNumber { value: "29021272" },
  to: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
  value: BigNumber { value: "0" },
  nonce: 1,
  data: '0x506e9463',
  r: '0xe79ae3bd10730473eb41ba4fced3d231375605598b83156e9f25ccd4155e8b86',
  s: '0x072d8e6ff0582fa4f11cf2cd89075114033de2159de94926fb25792c143c9bb1',
  v: 0,
  creates: null,
  chainId: 31337,
  wait: [Function (anonymous)]
}

1 Answer 1

0

that's right cuz it is transaction (blockchain state has been modified and return value is visible only in EVM). If you want to get address of contract B there are 2 possible solutions that are comming to my mind.

  1. Create a event and emit it at the end of CreateB() and listen for event in your deploy script.
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;

contract A2 {
    event ContractBCreated(address contractBAddress); //creates event

    function CreateB() public {
        B b = new B(msg.sender, address(this));
        emit ContractBCreated(address(b)); //allows to read value from event
    }
}

contract B{

    address public parentA;
    address public owner;

    constructor(address _ownerOfB, address _a) {
        owner = _ownerOfB;
        parentA = _a;
    }
}
async function main() {
  const A = await ethers.getContractFactory("A2");
  const a = await A.deploy();
  
  const tx = await a.CreateB();
  const receipt = await tx.wait();
  console.log(receipt.events[0].args.contractBAddress); //read value from event
}
  1. Create return view function that returns address and call it. It will work cuz this is not a transaction (blockchain won't be modified).
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;

contract A {
    B contractB;

    function CreateB() public {
        contractB = new B(msg.sender, address(this));
    }

    function getContracBAddress() public view returns(address) {
        return address(contractB);
    }
}

contract B{

    address public parentA;
    address public owner;

    constructor(address _ownerOfB, address _a) {
        owner = _ownerOfB;
        parentA = _a;
    }
}
async function main() {
  const A = await ethers.getContractFactory("A");
  const a = await A.deploy();
  
  await a.CreateB();
  console.log(await a.getContracBAddress());
}

Your Answer

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

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