I'm trying to deploy new instances of my logic using a factory, but i'm not so sure how to do that. My assumption is that the package creates and deploys a beacon proxy for you, but how does one use that to create a new instance of the logic in a factory.
Code to reproduce
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "./BoxBeacon.sol";
import "./BoxV1.sol";
contract BoxFactory {
mapping(uint32 => address) private boxes;
BeaconProxy public immutable beacon;
constructor(address _beacon, bytes memory data) {
beacon = new BeaconProxy(_beacon, data);
}
function buildBox(
uint256 _age,
string memory _name,
uint32 _boxId
) public {
BeaconProxy box = new BeaconProxy(
address(beacon),
abi.encodeWithSelector(
BoxV1(address(0)).initialize.selector,
_age,
_name
)
);
boxes[_boxId] = address(box);
}
function getBeacon() public view returns (address) {
return address(beacon);
}
function getBoxByIndex(uint32 index) public view returns (address) {
return boxes[index];
}
}
The deployBeacon function deploys up to 2 contracts: an implementation (if it has not already been deployed) and a beacon.
The deployBeaconProxy function does not deploy the implementation or beacon. It only deploys 1 contract: a beacon proxy which points to an existing beacon.
If you are trying to deploy new beacon proxies using a factory, then you would be using your factory instead of deployBeaconProxy. In your example, your immutable beacon variable should not be a BeaconProxy, but it should be an UpgradeableBeacon (which can be the beacon address that was deployed by deployBeacon).
See this post for another example of a beacon proxy factory.
Thank you so much @ericglau, this helps a lot. I have another question though, so I watched your talk at the community meeting where you mentioned that we can create as many proxies as needed using deployBeaconProxy. I tested it out and i can see multiple instances are created which also achieves my aim. Is this the right way to do it or would it be better creating a factory like in the example. Also if this is the right way, do I still need to take care of things like transferring ownership or is that handled already if use my address as the deployer when deploying with the hardhat plugin. Apologies if my questions are too Noob, still getting used to the pattern.
The factory would provide an on-chain way of creating new instances, whereas deployBeaconProxy would need to be called through a script. It depends on your use case or how you want to deploy the new beacon proxies.
Thanks a lot @ericglau .. For anybody interested in how i went about this eventually. I used an hybrid solution.. I deployed a beacon and implementation using deployBeacon, but i wanted an on-chain solution for the factory. So my factory ended up looking like this
in your factory contract is unnecessary, correct? Since "upgrades.deployBeacon" creates an UpgradeableBeacon for us? I was able to deploy everything fine without that import in my factory contract, but want to double check that it's not indeed necessary for some reason @ericglau ?