January 28, 2026

Capitalizations Index – B ∞/21M

Implement upgradable ERC721 token with ZeppelinOS – maroton – Medium

Implement upgradable ERC721 token with ZeppelinOS – maroton – Medium

Introduction

Essentially, contracts deployed once to Ethereum can not be upgraded.
So, if there is a bug in the code it will be fatal to the product.
However, by using the Proxy pattern, it becomes possible to create contracts that can be upgraded.

Since understanding the proxy pattern is summarizing the following articles in a very easy-to-understand manner, I think that you read through this and see the continuation.
https://blog.zeppelinos.org/proxy-patterns/

In this article, I use ZeppelinOS library to implement upgradeable contract.
It is possible to write ProxyContract yourself without using ZeppelinOS, but using ZeppelinOS makes it unnecessary.

Sample module

Here is the sample.
https://github.com/shiruco/upgradable-ERC721-sample

The contents are explained below.
This shall be operated in the private chain of the local environment.

  1. Deploy SampleToken (ERC721)
  2. Deploy SampleToken_v1 (ERC721) that SampleToken’s upgrade version
  3. Confirm that the implementation of SampleToken has been changed to SampleToken_v1

Environment

My development environment is as follows. Perhaps it is better to have versions if you test.

ZeppelinOS 2.2.0
Truffle v5.0.4 (core: 5.0.4)
Solidity v0.5.0 (solc-js)
Ganache CLI v6.3.0 (ganache-core: 2.4.0)
Node v11.3.0

Installation of ZeppelinOS is here.

npm install -g zos
or
yarn global add zos

Source code explanation

In the contract directory there is a contract called SampleToken and SampleToken_v1.
Each code is as follows and the version information returned by the function is different.
(SampleToken returns v0. SampleToken_v1 returns v1)

SampleToken

I used a library called zos-lib and openzeppelin-eth.
zos-lib is a library for implementing upgradeable contracts and implements initialize function instead of constructor.
openzeppelin-eth is a library for implementing secure smart contracts.
It was slightly confused with the difference with openzeppelin-solidity, but it seems better to use openzeppelin-eth if you use ZeppelinOS.

All in all, you should use this package instead of openzeppelin-solidity if you are managing your project via ZeppelinOS.

pragma solidity ^0.5.0;

import 'zos-lib/contracts/Initializable.sol';
import 'openzeppelin-eth/contracts/token/ERC721/ERC721Full.sol';
import 'openzeppelin-eth/contracts/token/ERC721/ERC721Mintable.sol';

contract SampleToken is Initializable, ERC721Full, ERC721Mintable

function version() public view returns (string memory)
}

SampleToken_v1

pragma solidity ^0.5.0;

import "zos-lib/contracts/Initializable.sol";
import 'openzeppelin-eth/contracts/token/ERC721/ERC721Full.sol';
import 'openzeppelin-eth/contracts/token/ERC721/ERC721Mintable.sol';

contract SampleToken_v1 is Initializable, ERC721Full, ERC721Mintable

function version() public view returns (string memory)
}

Deploy with zos command

We will deploy this contract and check its operation.
After installing npm modules, initialize the ZeppelinOS project with the following command.
Please specify the project name as you like.

$ zos init 

When initialization is completed, zos.json is generated directly under the project root. zos.json contains contract information and version information of the ZeppelinOS project.
Continue to add the SampleToken contract to the ZeppelinOS project with the following command.

$ zos add SampleToken

Next, we will deploy SampleToken, but this time I will set up a private chain locally as a deployment destination. Using ganache-cli, start up at port 7545.

$ ganache-cli -p 7545 -d

Now that you are ready, deploy with the command below. network is local. It refers to the information defined in truffle-config.js.

$ zos push --network local

If successful, the zos..dev.json file is generated. Looking at the contents, you can see that address is assigned to the SampleToken contract, and it is deployed successfully.
At this point the content of the proxies field is empty.

Next we will deploy ProxyContract for this contract. To deploy ProxyContract, use the following command. Passing name and symbol as arguments.

$ zos create SampleToken --init initialize --args="SampleToken,STKN" --network local

If deployed successfully, ProxyContract ‘s address should be in proxies field of zos..dev.json.
And the implementation field points to the address of SampleToken.
I think that you can access SampleToken via ProxyContract. Actually try it.

$ truffle console --network local
truffle(local)> token = await SampleToken.at(<proxy-address>)
truffle(local)> token.version()
'v0'

It seems that it is going well because “v0” has returned.

Next upgrade SampleToken. SampleToken_v1 is an upgrade version and will deploy this as before.
We add SampleToken_v1 as an alias of SampleToken and deploy it.

$ zos add SampleToken_v1:SampleToken
$ zos push --network local

Since ProxyContract has already been deployed, it is not create but it updates it.

$ zos update SampleToken --network local

This completes the upgrade process.
The implementation field’s address in the proxies field of zos..dev.json has been changed to point to the address of SampleToken_v1.
Let’s check again.

$ truffle console --network local
truffle(local)> token = await SampleToken.at(<proxy-address>)
truffle(local)> token.version()
'v1'

Since v1 was returned, it was upgraded successfully.

Deploy with Truffle

we deployed with the zos command, but migration files are prepared for the sample, so it can be checked also by truffle migrate, so please try it.

$ zos init 
$ truffle migrate --network local

Let’s check.

$ truffle console --network local
truffle(local)> token = await SampleToken.at(<proxy-address>)
truffle(local)> token.version()
'v1'

😀

Published at Sun, 24 Feb 2019 15:03:37 +0000

Previous Article

HYBSE, GMEX and MINDEX Collaborate to List the World’s First Multi-Asset Stable Token in Mauritius

Next Article

Bitcoin Crashes $500 in Minutes, Profit Taking, Short Making or What?

You might be interested in …

Coinbase: BTC Withdrawals to PayPal for EU Nations

Coinbase: BTC Withdrawals to PayPal for EU Nations On February 5, Cryptocurrency exchange Coinbase announced that it was extending support for PayPal withdrawals to all their customers in the European Union as well as European […]