OpenZeppelin Upgrades: Step by Step Tutorial for Hardhat

I’m stuck on the penultimate step … it tells me that an address is not registered. That address does not belong to anything in the project!. I don’t know where it comes from.

The error:

Preparing upgrade...
Error: Deployment at address 0xE8f000B7ef04B7BfEa0a84e696f1b792aC526700 is not registered

I think you're preparing an upgrade for a proxy whose current implementation is that address. But it's an unknown address for the plugins, either because you didn't deploy it with the plugins in the same project, or you deleted the network file that contained its metadata.

So do you recommend that I start everything from scratch?

If that's an option for you, it will be the fastest route. Currently you can't easily. add an implementation in the network file after it has been deployed. Track issue this issue for updates:

Is there an equivalent, detailed tutorial for the UUPS proxy pattern?

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!


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