How to Upgrade an ERC-721 Token with OpenZeppelin UUPS Proxies and Hardhat (Part 3)
Last updated
Was this helpful?
Last updated
Was this helpful?
In this tutorial, you'll learn how to upgrade your ERC-721 smart contract using the (Universal Upgradeable Proxy Standard) pattern and Hardhat. We'll first cover how the upgradeable proxy pattern works, then go through step-by-step implementation and upgrade verification, explaining each part clearly.
In traditional smart contracts, you can't change the logic once deployed, which can be risky if you find bugs or want to add new features. The upgradeable proxy pattern solves this by separating your contract into two parts:
Proxy Contract: Stores the state (data) and delegates all calls to the logic contract.
Logic Contract: Contains the actual business logic and can be replaced or upgraded.
When you upgrade your smart contract, you deploy a new logic contract and point your proxy contract to this new logic. The proxy stays at the same address, retaining your data and allowing seamless upgrades.
Important Note: In upgradeable contracts, constructors aren't used because the proxy doesn't call the constructor of the logic contract. Instead, we use an initialize
function marked with the initializer
modifier. This function serves the role of the constructor—setting up initial values and configuring inherited modules like ERC721
or Ownable
. The initializer
modifier ensures this function can only be called once, helping protect against accidental or malicious re-initialization.
⚠️ Complete as we continue from this example. Part 2 is optional.
Basic understanding of smart contracts.
Basic understanding of and JavaScript.
Basic understanding of and .
ECDSA account from the .
Install necessary dependencies if you haven't done so. For part 3 of this tutorial series, we're adding two extra dependencies:
@openzeppelin/contracts-upgradeable
: This is a version of the OpenZeppelin Contracts library designed for upgradeable contracts. It contains modular and reusable smart contract components that are compatible with proxy deployment patterns, such as UUPS.
@openzeppelin/hardhat-upgrades
: This Hardhat plugin simplifies deploying and managing upgradeable contracts. It provides utilities like deployProxy
and upgradeProxy
and automatically manages the underlying proxy contracts. This plugin is imported in the hardhat.config.js
file, so we can use it.
Create erc-721-upgrade.sol
in the contracts
directory:
initialize
function: Replaces the constructor in upgradeable contracts, setting initial values and calling necessary initializers.
initializer
modifier: Ensures the initialize function is only called once.
_authorizeUpgrade
: Ensures only the owner can authorize upgrades.
Compile the contract:
Create deploy-upgradeable.js
under the scripts
directory:
deployProxy
function: Deploys the logic contract behind a proxy, calling the initializer function (initialize
) automatically.
initializer: "initialize"
: Explicitly specifies which function initializes the contract.
kind: "uups"
: Specifies using the UUPS proxy pattern.
Deploy your contract:
Make sure to copy the smart contract address for your ERC-721 token.
Let's upgrade your contract by adding a new version
function. Create erc-721-upgrade-v2.sol
in your contracts
folder:
Adds a simple version
method to demonstrate the upgrade. Note that we are extending the "MyTokenUpgradeable" contract.
Compile the upgraded version:
Create upgrade.js
script to upgrade and verify the new functionality:
upgradeProxy
: Replaces the logic contract behind your existing proxy with the new version.
proxyAddress
: Points to the proxy contract that manages storage and delegates calls to logic contracts. Upgrading involves replacing the logic without altering the stored data. Make sure to replace the proxy contract address with the address you've copied.
Verification step: Calls the new version
method to ensure the upgrade succeeded.
Run this upgrade script:
Output confirms the upgrade:
Security: Upgrade functions can be restricted, ensuring only authorized roles can perform upgrades.
Data Retention: Maintains all token balances and stored data during upgrades.
Flexibility: Enables easy updates for new features, improvements, or critical fixes without redeploying a completely new contract.
Congratulations! 🎉 You've successfully implemented and upgraded an ERC-721 smart contract using OpenZeppelin’s UUPS proxy pattern with Hardhat.
Writer: Michiel, Developer Relations Engineer
Editor: Luis, Sr Software Developer
Editor: Krystal, Technical Writer
|
|