Creating upgradeable contracts from Solidity, is it mandatory to use App.sol?

Is it mandatory to use App.sol if i need to upgrade Contracts From Solidity?

1 Like

Hi @rdemeraT,

Welcome to the community :wave:

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

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!!

1 Like

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.