How to Create a Contract from Another Contract Using Solidity

·

Creating smart contracts that can deploy other contracts is a powerful feature in Solidity. This pattern, known as the contract factory, enables developers to dynamically instantiate new contract instances based on a predefined template. It's widely used across decentralized finance (DeFi), NFT platforms, and token launch tools.

In this guide, we’ll explore how to use Solidity’s new keyword to create a contract factory, understand its inner workings, and walk through a complete implementation with testing using HardHat. Whether you're building liquidity pools or enabling users to mint personalized tokens, mastering this concept is essential for scalable dApp development.

Understanding the Contract Factory Pattern

A contract factory is a design pattern where one smart contract (the factory) deploys multiple instances of another contract (the template). Each deployed instance inherits the logic of the template but can have unique state variables initialized at deployment time.

This approach offers several advantages:

👉 Discover how blockchain developers streamline contract deployment workflows.

Common Use Cases

The factory pattern powers many real-world applications:

These examples highlight the flexibility and reusability enabled by dynamic contract creation.

Core Implementation: Building a Bank Factory

Let’s build a simple yet functional example — a BankFactory that creates Bank contracts. Each bank will have:

Step 1: Define the Template – The Bank Contract

This is the blueprint used for every new instance:

contract Bank {
    uint256 public bank_funds;
    address public owner;
    address public deployer;

    constructor(address _owner, uint256 _funds) {
        bank_funds = _funds;
        owner = _owner;
        deployer = msg.sender; // This will be the factory address
    }
}

When a new Bank is created, it stores:

Step 2: Build the Factory – The BankFactory Contract

Now, implement the factory that instantiates Bank contracts:

contract BankFactory {
    Bank[] public list_of_banks;

    function createBank(address _owner, uint256 _funds) external {
        Bank newBank = new Bank(_owner, _funds);
        list_of_banks.push(newBank);
    }
}

Key points:

Once deployed, calling createBank(owner, 100) generates a fresh contract with those parameters — no manual deployment needed.

Testing with HardHat: End-to-End Walkthrough

To verify functionality, we'll compile and test our contracts using HardHat, a popular Ethereum development environment.

1. Set Up Your Project

Initialize a new Node.js project and install HardHat:

npm install --save-dev hardhat
npx hardhat

Choose "Create a JavaScript project" and follow prompts.

2. Add the Solidity Code

Create contracts/BankFactory.sol and paste both contracts inside.

3. Compile the Contracts

Run:

npx hardhat compile

You should see confirmation that both Bank and BankFactory compiled successfully.

4. Write a Test Script

Create test/bank-test.js with the following:

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("BankFactory and Bank Deployment", function () {
  it("Should deploy banks and store correct data", async function () {
    const BankFactory = await ethers.getContractFactory("BankFactory");
    const bankFactory = await BankFactory.deploy();
    await bankFactory.deployed();

    const owner = "0x0d8D32B83aaBBB675333468E4794eE0cDE666666";
    
    await bankFactory.createBank(owner, 69420);
    await bankFactory.createBank(owner, 100);
    await bankFactory.createBank(owner, 113377);

    const bankAddresses = await bankFactory.list_of_banks();
    
    const Bank = await ethers.getContractFactory("Bank");
    const bank1 = Bank.attach(bankAddresses[0]);
    const bank2 = Bank.attach(bankAddresses[1]);
    const bank3 = Bank.attach(bankAddresses[2]);

    expect(await bank1.owner()).to.equal(owner);
    expect(await bank1.bank_funds()).to.equal(69420);

    expect(await bank2.bank_funds()).to.equal(100);
    expect(await bank3.bank_funds()).to.equal(113377);

    console.log("All banks created successfully with correct state.");
  });
});

5. Run the Test

Execute:

npx hardhat test

If everything works, you’ll see a passing test and logs confirming each bank’s state.

👉 See how leading Web3 projects automate contract deployment at scale.

Frequently Asked Questions (FAQ)

Q: Can a factory track all deployed contracts?
A: Yes. By storing contract addresses in an array (like list_of_banks), the factory maintains full visibility and allows iteration or lookup later.

Q: Is there gas overhead when creating contracts dynamically?
A: Yes. Each new operation incurs higher gas due to bytecode deployment. Optimize by minimizing constructor logic and reusing libraries.

Q: Can deployed contracts be upgraded?
A: Not directly. Since each instance is immutable, consider using proxy patterns if upgradability is required.

Q: How do I interact with a newly created contract externally?
A: Use the contract ABI and its known address (from events or arrays) to connect via Ethers.js or Web3.js.

Q: Should I emit events when creating contracts?
A: Absolutely. Emitting an event like BankCreated(address owner, address bankAddress) improves transparency and indexability.

Q: Can anyone call the create function?
A: In our example, yes (external). Add access control (e.g., onlyOwner) if you want to restrict who can create contracts.

Keywords for SEO Optimization

Core keywords naturally integrated throughout this article include:

These terms align with common developer search queries related to advanced Solidity programming and dApp architecture.

Final Thoughts

Mastering contract factories unlocks scalable and modular smart contract architectures. From DeFi protocols to no-code platforms, this pattern empowers developers to build systems where users can generate customized logic without direct blockchain interaction.

By combining clean Solidity syntax with robust testing in HardHat, you ensure reliability and maintainability — critical for production-grade applications.

👉 Accelerate your smart contract development cycle with professional tools.