Stages pattern (also called state machine pattern: State Machine | solidity-patterns) is a pattern in smart contract development used to implement contracts which go through different phases.
Iād like to implement stages pattern as a plugin in Cairo. Each stage would be a separate module. Additionally there would be a main contract which would hold common storage and functions. A plugin would then merge those modules into a proper cairo contract.
An example contract using the hypothetical plugin:
#[staged_contract]
mod Pool {
use starknet::ContractAddress;
// Common storage variables and functions
struct Storage{
owner: ContractAddress,
max_contribution: u256
}
#[constructor]
fn constructor(...){
...
}
}
#[initial_stage(Pool)]
mod Initialization {
fn transition(...) {
// Transition to the next stage
stage(Contribute);
}
// Storage variables and functions used only in this stage
// If called in another stage the function will fail
...
}
#[stage(Pool)]
mod Contribute {
fn transition(...) {
stage(Collect);
}
...
}
#[stage(Pool)]
mod Collect {
// End state - no transitions
...
}
The main pros of the plugin are:
- Less error-prone code
- Easier manual analysis
- Due to standardization and more declarative approach automatic tools could utilize the information about different stages and be aware of it
For example, utilizing the information one could build a tool to visualize staged contract as a state diagram showing transitions between stages, or a tool that yields a different ABI depending on current stage.
If the plugin proves to be useful some other patterns may also be implemented using a similar approach. For example, access restriction could be implemented in a way that each module represents an interface for a different role in the system.
Would you use such a plugin? Any feedback is appreciated!