Problem
Say I have a contract A that, inside it's constructor, deploys a contract B. Now if I deploy A using hardhat-deploy, artifacts are generated, the contract is verified on etherscan etc. but the deployment of B is not known to hardhat-deploy.
Proposed Solution
It would be awesome if one could configure the deployment of A in a way to make it known to hardhat-deploy that this will also deploy a contract B, whose address can be read from A using function getB() and then have all the artifacts created etc as if hardhat-deploy deployed B itself. E.g. this could be configured by extending the DeployFunction with a field imlpicitDeployments of the form
That is, each object in the implicitDeployments array would have a string field contract and a field addressGetter that is a function(HardhatRuntimeEnvironment): Promise<string>. Of course, this is just a rough sketch.
Alternatives I've considered
I can use the usual contract dependencies to split the deployments of A and B. E.g. I first deploy B and make it a dependency of A, then in A's deployment I read the address of B and pass it to the constructor of A.
Additional context
There are situations where two contacts depend on each other. E.g. take the following minimal example
contract A is Ownable {
address public b;
function setB(address _b) external onlyOwner {
b = _b;
}
}
contract B {
address public immutable a;
constructor(address _a) {
a = _a;
}
}
Now I have to 1. deploy A, 2. deploy B passing the address of A to its construtor and 3. call A.setB() with the address of B. This can also nicely be done with contract dependencies.
An alternative solution is to have the following alternative constructor for A:
contract AWithBDeployment is A {
constructor() {
b = address(new B(address(this));
}
}
Now all I have to do it deploy A and B will be automatically deployed and both contracts are setup correctly. However, B would be invisible to hardhat-deploy and no artifacts generated, no etherscan verification etc.
Problem Say I have a contract
A
that, inside it's constructor, deploys a contractB
. Now if I deployA
usinghardhat-deploy
, artifacts are generated, the contract is verified on etherscan etc. but the deployment ofB
is not known tohardhat-deploy
.Proposed Solution It would be awesome if one could configure the deployment of
A
in a way to make it known tohardhat-deploy
that this will also deploy a contractB
, whose address can be read fromA
using functiongetB()
and then have all the artifacts created etc as ifhardhat-deploy
deployedB
itself. E.g. this could be configured by extending theDeployFunction
with a fieldimlpicitDeployments
of the formThat is, each object in the
implicitDeployments
array would have astring
fieldcontract
and a fieldaddressGetter
that is afunction(HardhatRuntimeEnvironment): Promise<string>
. Of course, this is just a rough sketch.Alternatives I've considered I can use the usual contract dependencies to split the deployments of
A
andB
. E.g. I first deployB
and make it a dependency ofA
, then inA
's deployment I read the address ofB
and pass it to the constructor ofA
.Additional context There are situations where two contacts depend on each other. E.g. take the following minimal example
Now I have to 1. deploy
A
, 2. deployB
passing the address ofA
to its construtor and 3. callA.setB()
with the address ofB
. This can also nicely be done with contract dependencies.An alternative solution is to have the following alternative constructor for
A
:Now all I have to do it deploy
A
andB
will be automatically deployed and both contracts are setup correctly. However,B
would be invisible tohardhat-deploy
and no artifacts generated, no etherscan verification etc.