Is it mandatory to use App.sol if i need to upgrade Contracts From Solidity?
Hi @rdemeraT,
Welcome to the community
You would only use App.sol if you were creating Ethereum Packages but the plan is to remove this contract. (See OpenZeppelin/openzeppelin-sdk#1488)
I haven’t ever used App.sol myself whilst creating upgradeable contracts.
To learn more about upgrades see the Learn guide: Upgrading Smart Contracts
- Buidler user: Create an upgradeable contract using OpenZeppelin Buidler Upgrades
- Truffle user: Create an upgradeable contract using OpenZeppelin Truffle Upgrades
Thanks Andrew!!
I will definitely use @openzeppelin/truffle-upgrades , it is a lot easier than my previous implementation to upgrade contracts!!
The way i used to do it was: first i deploy the upgradeable contract
let upgradeableContract = await MyUpgradeableContract.new();
let proxy = await Proxy.new(upgradeableContract.address, OWNER_ACCOUNT, []);
upgradeableContract = await MyUpgradeableContract.at(proxy.address);
and when i wanted to updated the logic i followed the next steps:
**MyUpgradeableContract has new features
let newContract = await MyUpgradeableContract.new({from: OWNER_ADDRESS });
let proxyContract = await Proxy.at(proxy.address);
await proxyContract.upgradeTo(newContract.address, {from: OWNER_ADDRESS });
To create upgradeable contracts from Solidity i dont know if it is possible to create a Factory contract that can deploy different types of instances, for example
contract MyFactory {
using Proxies for Proxies.ProxyFactory;
struct Proxies.ProxyFactory factoryFirstContract;
struct Proxies.ProxyFactory factorySecondContract;
constructor() public {
factoryFirstContract = Proxies.newFactory(FirstContract.creationCode);
factorySecondContract = Proxies.newFactory(SecondContract.creationCode);
}
function deployInstanceFirstContact(address admin, bytes initializerData) public {
factoryFirstContract(admin, initializerData);
}
function deployInstanceSecondContact(address admin, bytes initializerData) public {
factorySecondContract.deploy(admin, initializerData);
}
}}
What i have in my mind is to import MyFactory contract and make all the Instance deployment
import "./openzeppelin/Initializable.sol";
import "./MyFactory.sol";
contract CloudBrightByteFactory is Initializable {
bytes32 private currentVersion;
function initialize(bytes32 memory version¡) public initializer {
currentVersion = version;
}
function CreateTeam(address admin, bytes teamData) public {
...
MyFactory.deployInstanceFirstContact(admin, teamData)
}
function CreateStudent(address admin, bytes studentData) public {
...
MyFactory.deployInstanceSecondContact(admin, studentData)
}
}
The thing i dont have very clear is how to update all the instances of a contract created by MyFactory or if i got to store any address to make the upgrade possible, im a little lost hahah
Could work something like this?
let newContract = await MyUpgradeableContract.new({from: OWNER_ADDRESS });
let proxyContract = await ProxyFactory.at(proxyFactory.address);
await proxyContract.upgradeTo(newContract.address, {from: OWNER_ADDRESS });
I tried to find examples like this https://github.com/OpenZeppelin/openzeppelin-sdk/tree/master/examples/creating-instances-from-solidity but i dont find a clear answer
Thank a lot for the help!!
Hi @rdemeraT,
If you want to deploy via Truffle or Buidler, then I would recommend using the Upgrades plugins.
If you want to deploy upgradeable contracts using Solidity then I recommend inheriting from ProxyFactory. You just need to pass in your implementation address, your admin address (could be a ProxyAdmin if you wanted) and any initialization.
To upgrade proxy contracts you do need to upgrade each contract individually. So you would need to keep a list either on or off chain if you wanted to upgrade multiple contracts.
If you want to upgrade all the upgradeable contracts in one go, you could look at a different upgrade pattern.