- Published on
Solidity - Simple Contract Factory
874 words5 min read–––
Views
- Authors
- Name
- Saikrishna Reddy
Simple Contract Factory in Solidity
In Solidity, a factory is a contract that will deploy multiple instances of other contracts. (More on this later - different factory patterns, when to use, etc...🔄)
Context - when these factories are helpful?
There can many applications where businesses or individuals want to deploy similar contract but want to have different data. Example, Loans. All the loans have same functionality like taking loans, repaying, interest rates etc,... but based on businesses or individuals the data will be different. So, here factories implementation will be helpful to deploy contract for each business using the same Loan template.
Here you can find :
- Creating child contracts
- Store child contract addresses.
- Cast contract pointer to address.
- Call functions of child contract
- Caveat when admin is contract. (Here loan factory.)
pragma solidity ^0.8.7;
contract LoanFactory {
struct LoanDetails {
uint amount;
uint period; //days
}
address admin;
mapping(address => LoanDetails) public loans;
event LoanCreated(address loanAddress);
constructor() {
admin = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == admin, "Only owner");
_;
}
function createLoan() external onlyOwner {
//1. creating child contracts
Loan loan = new Loan(100); //loan here is the pointer to contract
LoanDetails memory details = LoanDetails(100, 10);
//2. Store child contract addresses.
loans[address(loan)] = details; //3. here address(loan) -> casting contract pointer to address.
emit LoanCreated(address(loan));
}
function getLoan(
address _loanAddress
) external view returns (LoanDetails memory) {
return loans[_loanAddress];
}
//5. Caveat when admin is contract
/**
* this withdraw function must be available in the factory contract. Otherwise there will be now way to call withdraw on child.
* withdraw on the child can only be called by the owner. In this case owner will be LoanFactory. So, only loanfactory can call the withdraw on Loan contract.
* Deploy on remix, play with it and have fun😉.
*/
function withdraw(
address loanAddress
) external view returns (string memory) {
Loan loan = Loan(loanAddress);
//4.Call functions of child contract
string memory result = loan.withdraw();
return result;
}
function getAdmin(address loanAddress) external view returns (address) {
Loan loan = Loan(loanAddress);
address result = loan.getAdmin();
return result;
}
}
contract Loan {
address admin;
uint amount;
constructor(uint _amount) {
admin = msg.sender;
amount = _amount;
}
modifier onlyOwner() {
require(msg.sender == admin, "Only owner");
_;
}
function getAdmin() external view returns (address) {
return admin;
}
function withdraw() external view onlyOwner returns (string memory) {
//withdraw logic
return "Withdraw Success!";
}
}