Regenesis state migration - Current suggestion

In this post, we want to share our current thinking on how the actual migration would look like during StarkNet’s regenesis. Our goal is to create transparency and use your feedback to improve the mechanism and reach a solution that will be the least disruptive and allow applications to launch on StarkNet Alpha before the regenesis.

We highly recommend you read the Regenesis Update to undersrand the scope, timeline, and code migration before deep diving into this post around the state migration.

Wen Regenesis? The overall timeline

  • End of 2022 - introducing Cairo 1.0 language
  • Beginning of Q1 2023 - StarkNet would support the deployment and execution of Cairo 1.0 contracts.
  • A few months after that - blocking Cairo v0 deployment and interactions

We intend to have a fully alive and functional system in which contracts are gradually and seamlessly updated to Cairo 1.0 without breaking anything. At the end of this period, transactions attempting to call Cairo v0 code would fail.

We next detail the mechanisms that would allow us to achieve that - and what you, as the dapps developers, would need to do.

Moving forward with a backward compatible state

The fundamental feature allowing us to replace the contracts without breaking anything is preserving all contracts’ addresses. For example, imagine that your account contract owns three types of ERC-20 tokens and that you upgrade the account to Cairo 1.0. If you keep the same address, this change is transparent to the ERC-20 contracts. But if your address changes, the state of these contracts also needs to change.

The second thing we will apply to make this possible is backward compatibility of the storage layout. This means that the place in the state in which StarkNet stores variables won’t change between the Cairo v0 and the Cairo 1.0 versions of the contract (assuming the variable name and type is the same). Thus, developers can upgrade their contracts’ code, and things will continue to work without changing the contract’s state. To leverage on this invariant and guarantee a smooth transition, the dapps developers will need to verify that variable names in the new implementation match the names in the current one.

So how would the upgrade happen?

We will introduce a new system call that any contract could call, wether Cairo 0 or Cairo 1.0. It will have semantics: “Please deploy this class hash X with constructor arguments Y in my address.” Developers who have deployed Cairo 0 code and finished writing their Cairo 1.0 version of the implementation would use this system call to deploy their updated contract code at the same address as the old code. This implies that Application developers would need to include something along the following lines in their Cairo 0 contracts:

func upgrade_to_cairo_one()


// Implement the flow control your app / DAO needs to migrate the contract



// At this point, you contract will have the same address as before, but use its new cairo 1.0 code


Please note that, as the caller’s address is unaffected by performing a delegation call, this syscall can also be used from upgradable contracts that are used as a proxy pattern, such as account contracts. This means that if you have an upgradable contract, then updating it to Cairo 1.0 would still be straightforward:

  1. Update the implementation to have the said syscall
  2. When your proxy (which holds the storage) calls the syscall through the implementation, the proxy implementation will be changed and the address preserved.

Closing the Transition Period

At the end of the transition period, we would update the StarkNet OS and introduce the following breaking changes:

  • Cairo v0 contracts won’t be able to get deployed, nor they would be able to get executed as part of any transaction. We will enforce this by bumping the version of all Cairo 1.0 contracts to “1”, and ensure that any contract with version “1” is indeed written in Cairo 1.0
  • The systemcall used for migration will be deprecated. This, combined with the first change, would mean that applications and users will no longer be able to take part in the migration.

But you didn’t release the syscall API yet! How can I launch on mainnet like this?

To launch on mainnet over the next few weeks, you would need to either:

  1. Include an upgrade mechanism in your contract that would allow you to upgrade to a version that calls this system call later. (For example, with a proxy pattern, as we described above)

  2. Allow your contract to call any arbitrary function (which is a bit risky)

Notice that even when using option #1 you can upgrade your contract to non-upgradable, non proxy Cairo 1.0 code. Also, the overhead around deciding who can upgrade your contract is something you’ll have to think of anyway when you consider who can call the new syscall. Thus, we don’t view option #1 as more disruptive than the (much worse) option of waiting for the syscall to be implemented.

Let’s consider some scenarios to clarify the plan.

  • Alice is an end user. When Alice logs in to her wallet sometime during Q1, the wallet suggests Alice to upgrade her account contract (similar to what happens with minor 0.x version bumps). Alice upgrades the contract and her address stays the same, so she can still access all funds. Everything works for her seamlessly.
  • Bob and Charlie are dapps developers. They deploy on mainnet and decide to deploy the contract before the regenesis, after reading this post. They add the function “upgrade_to_cairo_one” to the contract implementation. They decided that to update the implementation, their contract would check inside the “upgrade_to_cairo_one” a multisig of both. After Cairo 1.0 is released, Bob and Charlie port their contract code to Cairo 1.0. Once done, they use upgrade_to_cairo_one (with both signatures) to update their app’s code to the Cairo 1.0 version of the contract. The new version is not upgradeable, and the app’s users don’t notice any change.
  • Daniela and Ernesto are dapps developers. They deployed on mainnet before reading this post. Their code is upgradable using a proxy pattern. They will wait for a version of their proxy contract to be released that implements upgrade_to_cairo_one(), and call it to change their proxy’s code. At this point, their proxy’s code will be Cairo 1.0, while their app code will be Cairo v0. Then they will work on the Cairo 1.0 code of their application. Once done, they will use their usual proxy update flow control to update their app’s code to Cairo 1.0.
  • Fabien and Gabrielle are dapps developers. They deployed on mainnet before reading this post. Their code is not upgradable using a proxy pattern. They will have to write a new version of their app using Cairo 1.0 and deploy it. They will design a process to copy the state of their existing application in Cairo v0 to the newly deployed Cairo 1.0 code. They will need to communicate with users to inform them to stop using the old application.
  • Hugo is a dapp developer who deployed on mainnet but did a career change and is now a painter. Hugo isn’t planning ever to update his contract to Cairo 1.0 version. As time passes, Hugo’s Application users start noticing something iffy and ask to withdraw their money. Users who wouldn’t quit the dapp before the end of the migration period would find out that their funds are stuck. We hope such a phenomenon will be scarce.

Thanks for the post!

Am I correct to assume that, for the regenesis to actually benefit the infrastructure supporters (node & SDK devs etc.), nodes will be syncing starting from the Regenesis Point instead of the block 0 we have today right?

Does that mean we will basically have a gigantic genesis state that we will need to download to kick start the sync?


Hugo became Dave in the last paragraph!


Thanks for sharing the detailed scenarios, Ohad. Well explained.


It was Hugo all along, I have no idea what you are talking about :slight_smile:

Also, thanks


Yep, you are correct.