The question is after deploying the clone contract (Openzeppelin clone https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol)
How should one initialize the values? If i understand correctly, Instead of constructor we must replace it with a function that initializes the value
Is there a way to create the contract & execute the function at the same time?
Or do i have to do it like this
address _clone = clone(contractToBeCloned);
ContractToBeCloned(_clone).myfunction(argument)
Is there a better way?
I don't believe there is a better way, you clone the contract and then call your initialize(...) function
ContractToBeCloned(_cline).initialize(... your params ...);
(assuming you're also using @openzeppelin/contracts/proxy/utils/Initializable.sol )
The way the EIP 1167 clone deployment works prevents you from passing any other data.
--
Alternatively what people do is create an Factory Contract with a function to create the clone and then call their init function the same function call.
Hello
Related question, does a constructor
MUST be implemented in the master contract? I.e. I've seen master contracts implementing an empty constructor like this
// solhint-disable-next-line no-empty-blocks
constructor() {}
I don't understand why an empty constructor is needed. As far as I understand it is only needed for pre-initializing common parameters before clones are deployed.
Be sure that the master contract is pre-initialized. You can usually accomplish this in your constructor as the only time the master contract constructor is called is during the master contract's creation. - https://github.com/optionality/clone-factory
I.e. what if I don't need to pre-initialize the master copy!
Thank you in advance,
Cosimo
Yes, you are correct that when using the Clones
contract from the OpenZeppelin library, you will need to use a separate function to initialize the values of the clone contract rather than a constructor.
To create the contract and execute the function at the same time, you can use the new
keyword and pass in the arguments for the function as part of the contract deployment.
Example of how you could do this:
pragma solidity ^0.7.0;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/proxy/Clones.sol";
contract MyContract {
// Declare the contract that you want to clone
MyContractToBeCloned contractToBeCloned;
function deployAndInitialize(address _contractToBeCloned) public {
// Deploy the clone contract
address clone = new Clones(_contractToBeCloned);
// Initialize the values of the clone contract
MyContractToBeCloned(_clone).initialize(/* arguments for initialize function */);
}
}
Alternatively, you can also use the create2
function to create and deploy the clone contract, and then call the initialization function separately.
pragma solidity ^0.7.0;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/proxy/Clones.sol";
contract MyContract {
// Declare the contract that you want to clone
MyContractToBeCloned contractToBeCloned;
function deploy(address _contractToBeCloned) public {
// Deploy the clone contract
address clone = Clones.create2(_contractToBeCloned, /* salt */);
// Initialize the values of the clone contract
MyContractToBeCloned(_clone).initialize(/* arguments for initialize function */);
}
}