I have a main contract deployed that exposes a method mintSubContract:
function mintSubContract(uint256 initialAmount) public returns (address) {
SubContract sub = new SubContract(msg.sender, address(this));
address subAddress = address(sub);
if (initialAmount > 0) {
_transfer(msg.sender, address(sub), initialAmount);
}
_subAddresses.push(address(sub));
sub.mint(msg.sender, 0);
return address(sub);
}
When I call this function in Hardhat's ethers like so:
const subContract address = await mainContract.mintSubContract(500);
At first I expected subContract to hold the address. Now because that contract method is not (and can't be) a view, it actually holds a transaction.
Right now this is how I end up getting the address of the deployed sub-contract:
const transaction = await mainContract.mintSubContract(500);
const result = await transaction.wait();
At this point the value in result is this:
{
"to": "0x0a", /* The main contract address */
"from": "0x01", /* The sender of the transaction */,
"more keys": "That are irrelevant at this point for this matter (I think)",
"events": [
{ /* The transfer event in case there is one */
"transactionIndex": 0,
"blockNumber": 18,
"transactionHash": "0x...",
"address": "0x...",
"topics": [ /* ... */ ],
"data": "0x01e4",
"logIndex": 0,
"blockHash": "0x...",
"args": [
"0x01", /* The sender of the transaction */
"0x0b", /* The newly deployed contract */
{
"type": "BigNumber",
"hex": "0x01f4" /* The amount (500) */
}
],
"event": "Transfer",
"eventSignature": "Transfer(address,address,uint256)"
},
{ /* <------ This event has no name! */
"transactionIndex": 0,
"blockNumber": 18,
"transactionHash": "0x...",
"address": "0x0b", /* The newly deployed contract */
"topics": [ /* ... */ ],
"data": "0x",
"logIndex": 1,
"blockHash": "0x4569d6a315dad67d218e3dc2055467da7bd69b6cd6c5c49084c11a6976286dd1"
}
]
}
In this scenario we have an initialAmount so we have a Transfer event in that transaction (from ERC20 specs). The other event is what I suppose is the Contract Creation. At this point I'm just guessing. Right now I get the address of the newly created contract like this:
const subContractEvent = result.events.find(e => e.event === undefined); // Get the event with no name
const subContractAddress = subContractEvent.address;
This feels very hacky and I can think of a few ways it could go wrong. So my question is: Is there a better way? If this is the only way, does it even make sense to try to return the address of the subContract from the mintSubContract() method?