如何获取由另一个合同部署的合同的地址



----开始编辑----

我不知道我以前做错了什么,但下面的代码不知何故对我不起作用,现在正在起作用,而且完全一样。我不知道我以前是怎么做的,也不知道我错过了什么,但这个最小的例子和我正在做的真正的项目现在都在工作。很明显,我改变了一些东西,但我不知道是什么。我只知道它现在起作用了。很抱歉给大家带来困惑,并感谢大家的帮助。

-----结束编辑-----

我是Solidity的新手,正在使用Factory模式从另一个合同部署合同。我正在尝试获取已部署合同的合同地址,但遇到了错误。

我已经尝试了这个问题的解决方案,但我得到了以下错误:Return argument type struct StorageFactory.ContractData storage ref is not implicitly convertible to expected type (type of first return variable) address.

这是我的代码:

// 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;
}
}

如何获取此合同地址,以便将其存储在ContractData结构体中?谢谢

我编译了您的合同,将其部署在Remix上,并与此设置进行了无问题的交互

pragma solidity >=0.7.0 <0.9.0;

我想你在之前的合同中就有这个

userAddressToStruct[_userAddress] = contractAddress;

而不是这个

userAddressToStruct[_userAddress].contractAddress = contractAddress;

您可以使用以下代码来获取已部署合约的地址:

address contractAddress;
(contractAddress,) = new StorageContract(_userAddress);
userAddressToStruct[_userAddress].contractAddress = contractAddress;