Factory contracts are contracts that create other contracts. They are useful for:
Dividing your app into parts, each with different responsibilities.
Extending the scope of your app by dynamically adding a piece of functionality.
Managing different parts of the app from a single location, etc.
Here are some examples of active projects that use factory contracts:
, where a Factory contract a new Child contract for every new pair supported on the exchange. (Cosmwasm v0.10).
, where a Parent "Bank" Contract which manages the funds a single "Game" Contract which manages the game logic. (Cosmwasm v0.10).
After the child contract is stored on chain, you can instantiate child contracts from the factory in the following manner:
Assume the child contract expects the following instantiate message:
To instantiate the child contract, you can send a from the parent with the child's instantiate message:
If you don't care about the reply, you can send a regular message instead:
Assume the child contract expects the following instantiate message:
To instantiate the child contract, send a message on the parent's response:
// example of an Instantiate Msg
#[derive(serde::Serialize, serde::Deserialize)]
pub struct OffspringInstantiateMsg {
pub example_field: i32,
}use cosmwasm_std::{SubMsg, Response};
use secret_toolkit::utils::{InitCallback};const OFFSPRING_INSTANTIATE_REPLY_ID: u64 = 1;
// Implement InitCallback on the OffsprintInit message
// to be able to convert it to cosmosMsg
impl InitCallback for OffspringInstantiateMsg {
const BLOCK_SIZE: usize = BLOCK_SIZE;
}
// populate the message
let init_msg = OffspringInstantiateMsg {
example_field: 1,
};
// build a submessage from the offspring init message
let init_submsg = SubMsg::reply_always(
initmsg.to_cosmos_msg(
"example_label".to_string(), // label for offspring contract
1, // offspring code id
"d519793af2...".to_string(), // offspring code hash
None, // funds amount
)?,
OFFSPRING_INSTANTIATE_REPLY_ID,
);
// then build the response with the submessage
Ok(Response::new().add_submessage(init_submsg))let init_cosmos_msg = initmsg.to_cosmos_msg(
"example_label".to_string(), // label for offspring contract
1, // offspring code id
"d519793af2...".to_string(), // offspring code hash
None, // funds amount
)?;
Ok(Response::new().add_message(init_cosmos_msg))// example of an Instantiate Msg
#[derive(serde::Serialize, serde::Deserialize)]
pub struct OffspringInstantiateMsg {
pub example_field: i32,
}use cosmwasm_std::{CosmosMsg, WasmMsg};
use secret_toolkit::utils::{InitCallback};// Implement InitCallback on the OffsprintInit message
// to be able to convert it to cosmosMsg
impl InitCallback for OffspringInstantiateMsg {
const BLOCK_SIZE: usize = BLOCK_SIZE;
}
let messages = vec![
initmsg.to_cosmos_msg(
"example_label".to_string(), // label for offspring contract
1, // offspring code id
"d519793af2...".to_string(), // offspring code hash
None, // funds amount
)?,
]);
// Then return the message from an entry point, for example on init:
Ok(InitResponse {
messages,
log: vec![],
})