State Machine
This smart contract set implements a state machine. State machines are usually used to represent a system where an entity goes through several sequential states.
Each state has different functions and different roles associated with it. You can call certain functions only if the state you are in is associated with that function. The different roles associated with a state are the roles who are allowed to perform transition to the next state from the given state.
Our templateset provides a powerful, highly customisable way to create a statemachine for your use case.
Description
Representation of a state
Each state in the statemachine is represented using a State
struct. A struct
is a data type in solidity used to represent an object containing different attributes. The State
struct is declared in the StateMachine.sol
file as follows:
struct State {
// a boolean to check if the state is actually created
bool hasBeenCreated;
// a mapping of functions that can be executed when in this state
mapping(bytes4 => bool) allowedFunctions;
// a mapping of all roles that have been configured for this state
mapping(bytes32 => bool) allAllowedRoles;
// a list of all the roles that have been configured for this state
bytes32[] allowedRoles;
// a list of all the preconditions that have been configured for this state
function(bytes32, bytes32) internal view[] preConditions;
// a list of callbacks to execute before the state transition completes
function(bytes32, bytes32) internal[] callbacks;
// a list of states that can be transitioned to
bytes32[] nextStates;
// function that executes logic and then does a StateTransition
bytes4 preFunction;
}
To create a state, you can call the createState
function which our templateset provides out of the box. It is defined in the StateMachine.sol
contract.
Defining a state
To comprehensively represent your state, you need to define:
- The next states that you can transition to from the given state (
nextStates
field) - The functions you can access when you are in the given state (
allowedFunctions
field) - The roles who can perform the state transition to the next state (
allowedRoles
field)
Our templateset allows you to do this very easily through the functions addNextStateForState
, addAllowedFunctionForState
and addRoleForState
. These functions are defined in the StateMachine.sol
file.
One thing to note is that these three functions can be only called by the admin. The admin is set to the address from which the contract creation transaction is sent.
Transitioning from a state
1. Pre-conditions
There are usually some conditions that need to be satisfed before transitioning to the next state. Our templateset allows you to effortlessly add these conditions using the preConditions
field. It is important to note that while defining pre-condition functions, you need to ensure they throw an exception when the condition fails. Add a pre-condition for a state using addPreConditionForState
function.
2. Callbacks
Before you transition to another state, there may be several actions you need to perform first. To accomodate for this, our templateset provides support for callbacks
. callbacks
for a given state are functions which are called before moving to the next state from the given state. Add a callback for a state using addCallbackForState
function.