OpenZeppelin Upgrades: Step by Step Tutorial for Hardhat

Sorry, the other tutorial you've seen is the closest it gets: UUPS Proxies: Tutorial (Solidity + JavaScript)

1 Like

A post was split to a new topic: Execute upgrade using different signer

Ah, I see. Would you be able to give me an example of what a hardhat deploy script with a UUPS contract would look like? The script I currently use (non-upgradable) deploys the contract and copies its address and ABI over to the frontend app. In a UUPS contract scenario, what might such a script look like? Thank you very much for your help so far.

If you want you can share the script in a new post and we can go over the necessary changes.

I believe all that should be required in the script is to add { kind: 'uups' }

1 Like

@abcoathup Thank you for great tutorial.
I could not understand what initializer options are.
box = await upgrades.deployProxy(Box, [42], {initializer: 'store'});

Are there any options other than 'store' ?
Any other reference about initializer ?

Hi, welcome! :wave:

I think for the initializer option, it means when you deploy a proxy contract, you want to execute a function that is equal to the constructor in the implementation contract, and for more details, I think you can have a look at the documentation: Writing Upgradeable Contracts - OpenZeppelin Docs

1 Like

@Skyge Thank you for your reply.

I understood that we can use initialize as constructor.

Could you tell me why you are using store in this sample code?
Also, do you know any other option other than store?

I tried finding these answers by reading openzeppelin source code and document, but I could not find the answer by myself.

I think the tutorial just show a way you can call a function when deploy a contract, so it can be any method you want to call, and it is ok if you want to call this function separately later.

In the tutorial, there are only three functions: store, retrieve and increment, two write data functions and one read data function, so if you do not want to call store, maybe you can try to call increment

1 Like

@Skyge Thank you. I really appreciate your answer.
Now I understand store comes from contract's functions, and we can call a contract function by using initialize option with deploy.

1 Like

Hi, amazing tutorial.
I think I have it more or less figured out but I am having an issue with typescript in tests and deployments.
For un-upgradeable contracts I am able to use a type from the typechain, so I have all the functions of the contract available.

On the other hand, when I use the upgrades.deployProxy function the return type is Contract and all methods are lost. Is there a way around this or am I doing something wrong?

Hi, thanks for the tutorial. I followed it step by step, and at the end it doesn't keep the store.
await box2.retrieve() returns 0 instead of '42', however, all the tests pass.
What can be the reason of it? Am I missing an important step here?

The Upgrades plugin doesn't directly support TypeChain yet. Sorry about that. You can probably do manual casting of the return type in the meantime...

You may be using the wrong address when you call the attach method.

I checked it several times, I copy the output of Box.sol deployment, then paste it into prepare_upgrade.js. I can see that the increment() function is there, and it works, however the initial state is 0 when I retrieve first.

As you can see on the screenshot below. If it's the wrong address, then which one I should paste? Also, note, that all tests are passing. Would really appreciate help here!

Un3titled

The address is wrong, you need to attach the proxy address (in your case 0x1E24...). The address shown in the console is the address of the implementation contract, which you should not interact directly with.

1 Like

What if instead of a multisig you want a community of token holders to approve an upgrade? How could we implement that without bypassing all the safety that the upgrades plugin provide?

The Upgrades plugin runs off chain and there is no way to enforce it on chain. Even with a multisig setup you're not using the plugin itself to upgrade. In the governance proposal for the upgrade you should include a link where people can verify the code of the new contract implementation, and where they could also verify upgade safety by themselves through running a test suite that uses the Upgrades plugin.

1 Like

help.

I completed all upgrades contract follow this Topic, thanks!
I transferred ownership to Gnosis Safe.

deployed my ERC1155 Contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract MyToken is Initializable, ERC1155Upgradeable, OwnableUpgradeable, UUPSUpgradeable {
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {}

    function initialize() initializer public {
        __ERC1155_init("https://akjx.com/token/{id}");
        __Ownable_init();
        __UUPSUpgradeable_init();
    }

    function setURI(string memory newuri) public onlyOwner {
        _setURI(newuri);
    }

    function mint(address account, uint256 id, uint256 amount, bytes memory data)
        public
        onlyOwner
    {
        _mint(account, id, amount, data);
    }

    function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
        public
        onlyOwner
    {
        _mintBatch(to, ids, amounts, data);
    }

    function _authorizeUpgrade(address newImplementation)
        internal
        onlyOwner
        override
    {}
}

now, I want to call setURI method, I found it is impossible to connect contract, [OpenZeppelin] app( Gnosis Safe's apps) only support upgrades.

Does anyone know how to connect my Gnosis Safe wallet to call setURI method?

To call functions on your contract you go through the normal Gnosis Safe process, not our OpenZeppelin app. Look for the "Transaction Builder" app in "Apps".

Hi abcoathup
Can you tell me about it
"
I want to ask that we've deployed an up-gradable contract yesterday on polygon by hardhat plugin and it was deployed in one single transaction and now today we're deploying the same up-gradable contract now from same hardhat it's deploying in 3 transactions can you tell me why it's taking 2 extra transactions?

contract address deployed in one single transaction:0x6a4581fffdeaC8246B2DC3662F1035B6F5E8e618
"