Skip to content

How To Get the Address of a Contract Deployed by Another Contract in Solidity

How To Get the Address of a Contract Deployed by Another Contract in Solidity

Introduction to contract interaction in Solidity

Solidity, the programming language used for Ethereum smart contracts, allows contracts to interact with each other. When one contract deploys another, it’s common to need the address of the deployed contract for further interactions. There are several ways to achieve this, depending on your specific requirements and constraints.

Using an external function to return the address

One common approach is to define an external function in the deploying contract that returns the address of the deployed contract. This function can be called by other contracts or externally by users.

pragma solidity ^0.8.0;

contract Deployer {
    address public deployedContract;

    function deploy() external {
        deployedContract = address(new MyContract());
    }
}

contract MyContract {
    // Contract logic...
}

In this example, the Deployer contract deploys MyContract and stores its address in the deployedContract variable. Other contracts or users can then query this address using the deployedContract public variable.

🔥 Check this course out: Create Your Own Ethereum Token in Just 30 Mins

Emitting an event with the address

Another approach is to emit an event containing the address of the deployed contract. Events are useful for notifying external entities about state changes within the contract.

pragma solidity ^0.8.0;

contract Deployer {
    event ContractDeployed(address indexed deployedAddress);

    function deploy() external {
        MyContract deployed = new MyContract();
        emit ContractDeployed(address(deployed));
    }
}

contract MyContract {
    // Contract logic...
}

Here, when Deployer deploys MyContract, it emits a ContractDeployed event containing the address of the deployed contract. External entities can listen to this event and capture the deployed contract’s address.

Using a factory design pattern

The Factory design pattern is a common solution for deploying multiple instances of a contract and keeping track of their addresses. In this pattern, a separate factory contract is responsible for deploying instances of another contract.

pragma solidity ^0.8.0;

contract MyContractFactory {
    event ContractDeployed(address indexed deployedAddress);

    function deploy() external {
        MyContract deployed = new MyContract();
        emit ContractDeployed(address(deployed));
    }
}

contract MyContract {
    // Contract logic...
}

In this setup, MyContractFactory serves as the factory contract responsible for deploying instances of MyContract. It emits an event upon deployment, providing the address of the new contract.

🔥 Check this course out: Build a One Piece Personality dApp With Solidity

Using return values in deployment functions

Solidity provides a way to return values from functions, even constructor functions, which can be useful for retrieving the address of the deployed contract.

pragma solidity ^0.8.0;

contract Deployer {
    function deploy() external returns (address) {
        return address(new MyContract());
    }
}

contract MyContract {
    // Contract logic...
}

In this scenario, the deploy function of the Deployer contract returns the address of the deployed MyContract. External callers can invoke this function and capture the returned address.

Call before you make a transaction

Before making a transaction to deploy a contract, you can first make a call to the factory contract to retrieve the address of the future contract. This approach allows you to obtain the address without actually deploying the contract, providing assurance and flexibility.

var address = web3.eth.contract(objectFactoryAbi)
    .at(contractFactoryAddress)
    .createObject.call("object");

In this code snippet, objectFactoryAbi represents the ABI (Application Binary Interface) of the factory contract, and contractFactoryAddress is the address of the factory contract. The .createObject.call("object") call simulates the deployment of the contract without actually committing the transaction. It returns the address where the contract will be deployed.

Once you have obtained the address, you can proceed with the transaction to deploy the contract:

var txHash = web3.eth.contract(objectFactoryAbi)
    .at(contractFactoryAddress)
    .createObject("object", { gas: price, from: accountAddress });

Here, .createObject("object", { gas: price, from: accountAddress }) initiates the transaction to deploy the contract. Ensure to specify the necessary gas and sender address (accountAddress) for the transaction to be processed successfully.

Calculate the future address

Alternatively, you can calculate the address of the future contract without actually deploying it. This method utilizes Ethereum’s address derivation algorithm to compute the address based on the factory contract’s address and nonce.

var ethJsUtil = require('ethereumjs-util');
var futureAddress = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
      contractFactoryAddress,
      await web3.eth.getTransactionCount(contractFactoryAddress)));

In this code snippet, ethereumjs-util library is used for Ethereum-specific utilities. generateAddress function computes the address based on the factory contract’s address (contractFactoryAddress) and the nonce, obtained using web3.eth.getTransactionCount(contractFactoryAddress). The resulting futureAddress represents the address where the contract will be deployed.

🔥 Check this course out: Build Hogwarts Sorting Hat dApp on Polygon

Conclusion

These are some of the methods you can employ to obtain the address of a contract deployed by another contract in Solidity. Each approach has its advantages and may be more suitable depending on the specific requirements of your application. Whether it’s through direct return values, events, external functions, call before initiating a transaction, or calculating the future address, Solidity offers flexibility in contract interaction to accommodate various use cases. Understanding these techniques will empower you to design robust and interoperable smart contracts on the Ethereum blockchain.

Try it out, ask us questions, and tell us how it went by tagging Metaschool on Social Media.

Follow us on –

🔮Twitter – https://twitter.com/0xmetaschool

🔗LinkedIn – https://www.linkedin.com/company/0xmetaschool/