1

-----START EDIT-----

I don't know what I was doing wrong before, but the code below was somehow not working for me, and now is working, and it's exactly the same. I don't know how or what I was missing before, but both this minimal example and the real project I am working on is working now. Obviously I changed something, but I can't figure out what. I just know it's working now. Sorry for the confusion and thanks to everyone for helping.

-----END EDIT-----

I am new to Solidity and am using the Factory pattern for deploying a contract from another contract. I am trying to get the contract address of the deployed contract, but I am running into errors.

I already tried the solution in this question, but I'm getting the following error: Return argument type struct StorageFactory.ContractData storage ref is not implicitly convertible to expected type (type of first return variable) address.

Here is my code:

// START EDIT (adding version)
pragma solidity ^0.8.0;
// END EDIT

contract StorageFactory {

  struct ContractData {
    address contractAddress; // I want to save the deployed contract address in a mapping that includes this struct
    bool exists;
  }

  // mapping from address of user who deployed new Storage contract => ContractData struct (which includes the contract address)
  mapping(address => ContractData) public userAddressToStruct;

  function createStorageContract(address _userAddress) public {

    // require that the user has not previously deployed a storage contract
    require(!userAddressToStruct[_userAddress].exists, "Account already exists");
    
    // TRYING TO GET THE ADDRESS OF THE NEWLY CREATED CONTRACT HERE, BUT GETTING AN ERROR
    address contractAddress = address(new StorageContract(_userAddress));

    // trying to save the contractAddress here but unable to isolate the contract address
    userAddressToStruct[_userAddress].contractAddress = contractAddress;
    userAddressToStruct[_userAddress].exists = true;
  }
}


// arbitrary StorageContract being deployed
contract StorageContract {
  address immutable deployedBy;

  constructor(address _deployedBy) {
    deployedBy = _deployedBy;
  }
}

How can I get this contract address, so I can store it in the ContractData struct? Thanks.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Scott
  • 1,207
  • 2
  • 15
  • 38

2 Answers2

1

I compiled your contract, deployed it on Remix, and interacted without issue with this setting

pragma solidity >=0.7.0 <0.9.0;

I think you had this in your contract before

 userAddressToStruct[_userAddress] = contractAddress;

instead of this

 userAddressToStruct[_userAddress].contractAddress = contractAddress;
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • This actually worked. Although I was trying to use `pragma solidity ^0.8.0`. Didn't realize the version would be that important or I'd have included it in my original post. Is there any way to use that version and have it work? May just go with your solution if I'm unable to get another working solution. Appreciate the response. – Scott Dec 03 '22 at 02:09
  • @Scott it works with `^0.8.0` as well. where do you write your code? – Yilmaz Dec 03 '22 at 02:13
  • Damn. I'm using remix. I tried reproducing using a minimal example, and it's working in the minimal example but not in my real project. I don't know why. I'm going to delete this question and try to figure it out more. Thanks for your help. – Scott Dec 03 '22 at 02:19
  • It works when both contracts are in the same Solidity file, but not when I import the `StorageContract.sol` into a separate `StorageFactory.sol` file. Bizarre. Anyway, thanks again. – Scott Dec 03 '22 at 02:26
  • 1
    @Scott it still works. I think you should take a break :) – Yilmaz Dec 03 '22 at 02:31
  • @Scott I think you had this before `userAddressToStruct[_userAddress] = contractAddress` – Yilmaz Dec 03 '22 at 03:02
  • Yup, you're right. Should of course be `userAddressToStruct[_userAddress].contractAddress = contractAddress` – Scott Dec 03 '22 at 13:55
0

You can use the following code to get the address of the deployed contract:

address contractAddress;
(contractAddress,) = new StorageContract(_userAddress);
userAddressToStruct[_userAddress].contractAddress = contractAddress;
DotNetRussell
  • 9,716
  • 10
  • 56
  • 111