1

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

  • Transactions do not return a value, to get a value from a transaction you can emit an event with the value as parameter, see here https://ethereum.stackexchange.com/questions/6380/how-to-get-values-returned-by-non-constant-transaction-functions. – Ismael Sep 20 '21 at 05:47

0 Answers0