Solidity Simple Upgradable Smart Contract

The smart contract is code immutable but not the states on the contract because it can be modified. The problem is once publishing the smart contract to the Ethereum network, the contract code cannot be changed. There is always some advantage and some drawback. There is a good reason being able to upgrade contracts. The most important part of immutability is making sure that nobody can make changes to the code afterwards. This makes Ethereum and Smart Contracts so incredibly powerful and the contract becomes trustworthy. It’s like burning the logic into the blockchain and nobody can change it or take it down. But recent hacks were all based on very simple programming errors and bugs could be fixed very easily if it was possible to upgrade these contracts. In this tutorial, I will provide you with a tutorial on upgradable smart contract.

To get started, use remix IDE // to create your upgradable smart contract. You will be able to understand after this tutorial.

Create a storage contract

First, add a new file call “MetaCoinStorage.sol” and copy paste the following source code. It will assign 10000 coins to the contract creator. This contract will store the states of the meta coin.

pragma solidity ^0.4.18;

contract MetaCoinStorage {

    mapping(address => uint) balances;

    mapping(address => bool) accessAllowed;

    function MetaCoinStorage() public {
        accessAllowed[msg.sender] = true;
        balances[tx.origin] = 10000;

    modifier platform() {
        require(accessAllowed[msg.sender] == true);

    function allowAccess(address _address) platform public {
        accessAllowed[_address] = true;

    function denyAccess(address _address) platform public {
        accessAllowed[_address] = false;

    function getBalance(address _address) public view returns(uint) {
        return balances[_address];

    function setBalance(address _address, uint _balance) public {
        balances[_address] = _balance;


Create a proxy contract

After that, create a new file call “MetaCoin.sol”, this contract will call the storage contract methods and handle logics of getBalance.

pragma solidity ^0.4.18;

contract MetaCoin {
	MetaCoinStorage metaCoinStorage;

	event Transfer(address indexed _from, address indexed _to, uint256 _value);

	function MetaCoin(address metaCoinStorageAddress) {
		metaCoinStorage = MetaCoinStorage(metaCoinStorageAddress);

	function sendCoin(address receiver, uint amount) returns(bool sufficient) {
		if (metaCoinStorage.getBalance(msg.sender) < amount) return false;
		metaCoinStorage.setBalance(msg.sender, metaCoinStorage.getBalance(msg.sender) - amount);
		metaCoinStorage.setBalance(receiver, metaCoinStorage.getBalance(receiver) + amount);
		Transfer(msg.sender, receiver, amount);
		return true;

	function getBalanceInEth(address addr) public view returns(uint){
		return ConvertLib.convert(getBalance(addr),2);

	function getBalance(address addr) public view returns(uint) {
		return metaCoinStorage.getBalance(addr)+1;

interface MetaCoinStorage {
    function getBalance(address _address) public view returns(uint);
    function setBalance(address _address, uint _balance) public;

library ConvertLib{
    function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount)
        return amount * conversionRate;

Deploy Contract

In the run tab, deploy the storage contract first, after that deploy the proxy contract.

Discover and fix the bug

The proxy contract getBalance method has a bug which is “+1” when getting the balance of the address. Erase “+1” on the getBalance method proxy contract and deploy it again.

Now you can try to call the method again from the new proxy contract, you will discover the bugs are fixed.

Solidity Simple Upgradable Smart Contract

Source Code

(Visited 623 times, 1 visits today)

Yong Loon Ng

Ng Yong Loon, better known as Kristofer is a software engineer and computer scientist who doubles up as an entrepreneur.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *