Upgradeable Smart Contracts

2,520 reads

If you’re simply looking for the code, you can find the repo here.

When you’re familiar with Ethereum (or blockchain in general) you’ve probably come across the word ‘immutable’. When thinking about blockchain we mainly associate this with the fact that the ledger and functional state of the system can not be tampered with or deleted. When thinking about smart contracts specifically I’d rather compare it to the definition of an ‘immutable object’.

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created

This means that once our contract is deployed onto the blockchain, it is set in stone. We can not change the state outside of it’s predefined scope (setters), but more importantly we can not change the code.

To solve this issue we’ll talk about a solution based on splitting our contract storage and logic into separate contracts while directing calls through a registry. After that we’ll go over some of the pro’s and cons.

Contract Managing Contracts (CMC)

The model will be based on the Five types model by Monax, updated for the newest Solidity language features to make it more understandable and readable. We will implement the following contracts:

CMC — A registry that keeps track of contracts in our system Controllers — Contracts that operate on our storage contracts Storage — Data store contract with the necessary getters and setters ALC — Contracts that contain application-specific logic, generally user entry-points

The action flow looks like you would expect from the naming if you have prior experience with web applications.

User →ALC →Controller →Storage

Base class for ALC’s, Controllers and Storage

Every contract we add to the register will start with a base class that sets and contains the ethereum address for our register, a modifier for contracts access control, an interface to get the address from contracts in the register and an option to delete the contract.

Contract Registry

Our contract registry will keep track of the contract addresses our system currently uses in a mapping. We’ll use bytes32 variables because we can’t have dynamic types (strings) as keys. We’ll add functions to add, get and remove functions from our registry and one to update the registry being used by our deployed contracts. (you can get Ownable.sol from OpenZeppelin)

That’s it! Now it’s time to illustrate how it works, to do so we’ll create a simple workflow that stores a variable x into our storage contract through an ALC and controller. Each contract will be deployed seperatly and added to the registry after creation. A good convention might be to give your contracts the same name as the one that they are defined with.

Putting it to the test

In the github repo you will find a file in the test folder with some basic unit tests. To run these, make sure you have truffle installed and Ganache running. Run the test command to run the unit tests:

truffle test

completed tests

Pro’s and Con’s

The two pro’s of this set-up are of course code maintainability and upgradeability. We can now deploy a new controller or ALC on top of our existing storage so that our user data remains intact.

The biggest cons are the gas costs. Deploying this baby will cost alot more than just deploying one contract, especially if the workflow is really simple. On top of that you/the user will be paying an additional 10% increase in gas costs when making state changes.

I understand there could be some trust issues with this for users, I don’t really see that as an argument however as they can easily check the register to check which contracts are being used.

Thanks for reading, I hope you enjoyed it and above all learned something new. This is just a basic model, a larger system would of course have more logic on the CMC and even different contract managers for different parts of the system.

If you want to learn more about solidity make sure to check out our dApp tutorial series and our token tutorials!

You’re always welcome to leave a tip and support free knowledge sharing if you enjoyed this article!

ETH — 0x6d31cb338b5590adafec46462a1b095ebdc37d50

Tags