Building a Factory Contract
A factory contract needs two core capabilities: storing contract bytecode and deploying it to new sub-accounts. Let's build this step by step.
Contract Structure
First, let's look at the basic structure of our factory contract:
Loading...
The factory contract stores the compiled bytecode in a Vec<u8> field. This bytecode will be deployed to each new sub-account we create.
Core Deployment Method
The heart of our factory is the deployment method. This function creates a new sub-account and deploys our stored contract to it:
Loading...
Let's break down what this method does:
- Creates a sub-account using the provided name
- Transfers the required deposit to cover account creation and storage costs
- Deploys the stored contract code to the new account
- Calls the initialization method on the deployed contract
Account Creation Promise
The Promise::new() chain handles the complex process of account creation and contract deployment:
Loading...
This promise chain:
- Creates the account with the specified initial balance
- Deploys the bytecode stored in
self.code - Calls the contract's initialization method
Contract Management
We also need a way to update the stored contract code for future deployments:
Loading...
The #[private] annotation ensures only the factory contract itself can update the stored bytecode.
Why Direct Input Reading?
Notice the env::input() approach instead of regular parameter deserialization. This is a gas optimization:
- Standard deserialization would parse the entire WASM file from JSON
- For large contracts, this consumes the entire gas limit
- Direct input reading bypasses this overhead
Initialization Method
Finally, we need an initialization method for when the factory is first deployed:
Loading...
This sets up the factory with an initial contract to deploy. The factory owner can later update this stored contract.
Cargo.toml Dependencies
Make sure your Cargo.toml includes the necessary dependencies:
[dependencies]
near-sdk = "4.1.1"
Building the Contract
Compile your factory contract:
cargo build --target wasm32-unknown-unknown --release
The compiled WASM file will be in target/wasm32-unknown-unknown/release/.
Now that we have our factory contract built, let's deploy it to testnet and upload our first contract template.