Upgrading Smart Contracts using OpenZeppelin Upgrade Plugin

Busayo Amowe
Coinmonks
7 min readMay 23, 2022

--

A bit of intro

When I came across upgradeable contracts, I was taken aback a bit. Upgrade? Why is upgrade a topic when smart contracts are designed to be immutable by default? Once a contract is created on the blockchain, there is no way to change it. You might have the same questions/thoughts as I had or even more. While researching how to write an upgradeable contract, I had a bit of a challenge understanding and finding a well-explanatory guide which is why I will be discussing some fundamentals in this article alongside showing you how to write a simple upgradeable smart contract using the openzepplin plugin.

The Why

Some scenarios call for modification of contracts. Relating it to regular daily lives, two parties who have signed a contract can decide to change agreements, perhaps they have to remove some terms or add some more or fix mistakes. As long as they both consent to it, it can be changed. On a blockchain such as Ethereum, it’s possible that a bug was found in a smart contract that has already been deployed to production or more functionalities are just required. It could be anything really. It definitely calls for an upgrade.

OpenZepplin

OpenZeppelin

OpenZeppelin is the leading company when it comes to securing products, automating, and operating decentralized applications. They protect leading organizations by performing security audits on their systems and products. They have a library of modular, reusable, secure smart contracts for the Ethereum network, written in Solidity. Thanks to the OpenZeppelin Upgrades Plugin, it’s quite easy to modify a contract while still preserving important things like address, state, and balance.

The How

Smart contracts can be upgraded using a proxy. Basically, there are two contracts:

  1. Contract 1 (proxy/point of access): This contract is a proxy or a wrapper that will be interacted with directly. It is also in charge of sending transactions to and fro the second contract that I would be talking about next
  2. Contract 2 (logic contract): This contract contains the logic.

One thing to note is that the proxy never changes, however, you can swap the logic contract for another contract meaning that the access point/proxy can point to a different logic contract (in other words, it gets upgraded). This is illustrated below

Source: https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies#upgrading-via-the-proxy-pattern

To learn more about the proxy concepts, visit the openzepplin proxy upgrade pattern docs page and openzepplin proxy page

Upgradeability Patterns

We have several upgradeability patterns. Listed below are four patterns

  • UUPS proxy: EIP1822
  • Transparent proxy: EIP1967 (We would be focusing on this in this article)
  • Diamond Storage: EIP2355
  • Eternal Storage: ERC930

Transparent Proxy (EIP1967)

Transparent proxies include the upgrade and admin logic in the proxy itself. I would refer to the admin as the owner of the contract that initiates the first upgrade.

Using the transparent proxy, any account other than the admin that calls the proxy will have their calls forwarded to the implementation. In the same vein, if the admin calls the proxy, it can access the admin functions, but the admin calls will never be forwarded to the implementation.

In summary, it’s best for the admin to be a dedicated account only used for its purpose which is obviously to be an admin.

Practical Steps

Prerequisite: knowledge of how to set up dev environment and how to write smart contracts. More info here

Let’s write an upgradeable contract! We will be openzepplin’s hardhat-upgrades plugin. To install, simply run

In your hardhat.config file, you need to load it in

I will be using js for this article

Your hardhat.config.js file should be similar to this

Contract 1 (contracts/Atm.sol) (proxy contract)

In your contracts folder, create a new .sol file. In this article, I would be simulating an atm/bank. So, create Atm.sol. The code should look similar to this

Test Contract

Test your contract in test/Atm-test.js as illustrated below

To test, run this command

Deploy Contract

!Important: In order to be able to upgrade the Atm contract, we need to first deploy it as an upgradeable contract. It is different from the deployment procedure we are used to. We are initializing that the start balance be 0. The script uses the deployProxy method which is from the plugin.

Create a deploy-atm.js script

You can decide to test this as well. If you wish to test, your test file should be similar to this

Test Script

After confirming tests,

Let’s deploy to local first, we use the run command and deploy the Atm contract to dev network.

At this point, we have successfully deployed and have our proxy and admin address.

Contract 2

We want to add a new feature to our contract, a simple feature which is to include an add function that adds 500 to our balance.

Create contracts/AtmV2.sol

Test Contract

Refer to how we tested Contract 1 and basically follow same logic.

Upgrade Contract

Now is the time to use our proxy/access point address. We would be using the upgradeProxy and 'getAdmin' methods from the plugin. Recall our proxy address from our deployment console above as we would be needing it here.

Create scripts/upgrade-atmV2.js. Your script should look similar to this

Test script

Create a scripts/AtmProxyV2-test.js. It should look similar to this

After confirming tests,

Let’s deploy our newly added contract with additional feature, we use the run command and deploy the AtmV2 contract to dev network.

To deploy on goerli, simply replace

with

There you have it, check for your addresses on Goerli Explorer and verify it.

For a view of all contracts, you can check out my contracts at

Summary

While it is a fast approach to use the openzepplin plugin and it varies across teams, a better way to understand and do upgrades is to copy the transparency proxy sol files and related sol files from openzepplin’s into your project. This protects you from upstream attacks.

This comes to the end of this article. Hope you learnt a thing or two. I would appreciate feedbacks as well! Kindly leave a comment. Happy building!

References:
https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable

https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/proxy

https://dev.to/yakult/tutorial-write-upgradeable-smart-contract-proxy-contract-with-openzeppelin-1916

Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing

Also, Read

--

--

Busayo Amowe
Coinmonks

A software engineer. Learning new technology trends,applying them to solve problems is fascinating to me.