I have three smart contracts:
An abstract one:
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol";
/**
- @title Base contract for state machines
*/
abstract contract StateMachine is AccessControl {
event Transition(address sender, bytes32 fromState, bytes32 toState);
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 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;
}
struct StateTransition {
bytes32 fromState;
bytes32 toState;
address actor;
uint256 timestamp;
}
StateTransition[] public history;
mapping(bytes32 => State) internal states;
bytes32[] internal possibleStates;
bytes32 internal currentState;
// a list of selectors that might be allowed functions
bytes4[] internal knownSelectors;
mapping(bytes4 => bool) internal knownSelector;
// a list of allowed functions per state
bytes4[] internal stateFunctions;
mapping(bytes32 => bytes4[]) internal stateFunction;
// To Check if there is a relation between one state and another
mapping(bytes32 => mapping(bytes32 => bool)) internal nextStateToState;
/**
- @dev Abstract function to setup the state machine configuration
*/
function setupStateMachine(address Admin) internal virtual {}
function createState(bytes32 stateName) internal {
require(!states[stateName].hasBeenCreated, "this state has already been created");
states[stateName].hasBeenCreated = true;
possibleStates.push(stateName);
}
/**
- @notice Configures the initial state of an object
*/
function setInitialState(bytes32 initialState) internal {
require(states[initialState].hasBeenCreated, "the initial state has not been created yet");
require(
currentState == 0,
"the current state has already been set, so you cannot configure the initial state and override it"
);
currentState = initialState;
}
}
My implementation (from which I want to create clones):
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./StateMachine.sol";
contract SupplyChain is StateMachine, Initializable {
bytes32 public constant STATE_DEMAND_GENERATED = 'DEMAND GENERATED';
bytes32 public constant ROLE_ADMIN = 'ROLE_ADMIN';
bytes32[] public _roles = [ROLE_ADMIN];
function initialize() public virtual initializer {
address Admin = msg.sender;
_setupRole(DEFAULT_ADMIN_ROLE, Admin);
_setRoleAdmin(ROLE_ADMIN, DEFAULT_ADMIN_ROLE);
setupStateMachine(Admin);
}
function setupStateMachine(address Admin) internal override {
//create all states
createState(STATE_DEMAND_GENERATED);
// add properties
setInitialState(STATE_DEMAND_GENERATED);
}
}
And then my proxy factory:
pragma solidity 0.8.6;
import "@openzeppelin/contracts/proxy/Clones.sol";
import "./SupplyChain.sol";
contract SupplyChainFactory {
address immutable proxyImplementation;
constructor() public {
proxyImplementation = address(new SupplyChain());
}
function createSupplyChain() external returns (address) {
address clone = Clones.clone(proxyImplementation);
SupplyChain(clone).initialize();
return clone;
}
}
I am currently only testing in Remix but right now when I click createSupplyChain(), it returns :
[vm] from: 0x5B3...eddC4 to: SupplyChain.(fallback) 0x1d1...3B8BD value: 0 wei data: 0x4a4...5a1b3 logs: 22 hash: 0xde0...0f27f
but in the decoded output I have nothing, can you guys explain me what I do wrong? or what I don't understand here? Thanks in advance