{"id":13410415,"url":"https://github.com/NethermindEth/0to1CairoDemo","last_synced_at":"2025-03-14T16:32:10.668Z","repository":{"id":163138581,"uuid":"618486644","full_name":"NethermindEth/0to1CairoDemo","owner":"NethermindEth","description":"Demo to upgrade your upgradeable cairo 0 proxy contract to cairo 1 via replace_class_syscall","archived":false,"fork":false,"pushed_at":"2023-04-26T15:34:30.000Z","size":371,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-05T09:45:44.134Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NethermindEth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-24T15:16:12.000Z","updated_at":"2024-02-16T06:54:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"a449612b-5c10-495f-922c-ef52495ee1a1","html_url":"https://github.com/NethermindEth/0to1CairoDemo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NethermindEth%2F0to1CairoDemo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NethermindEth%2F0to1CairoDemo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NethermindEth%2F0to1CairoDemo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NethermindEth%2F0to1CairoDemo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NethermindEth","download_url":"https://codeload.github.com/NethermindEth/0to1CairoDemo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243610202,"owners_count":20318920,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:01:06.722Z","updated_at":"2025-03-14T16:32:10.652Z","avatar_url":"https://github.com/NethermindEth.png","language":"Python","funding_links":[],"categories":["Tutorials"],"sub_categories":[],"readme":"# How to upgrade your Cairo 0 contracts to Cairo 1 using `replace_class`\n\n## Why upgrade to Cairo 1.0 ?\n\nWith Regenesis approaching on Starknet, Cairo 0.x will soon be deprecated in favour of Cairo 1. To ensure your contracts continue working after Regenesis, it's important to migrate them from Cairo 0.x to Cairo 1. As Starknet Alpha v0.11.0 is now live on Mainnet, Cairo 1 contracts can now deployed and current Cairo 0 contracts can now be upgraded with provided `replaced_class` syscall without necessitating a change in contract address.\n\n## Upgrading your Upgradable Cairo 0.x contracts to Cairo 1\n\nIn Cairo 0.x, in order to have an upgradable Cairo 0.x contracts, you will often utilize a `Proxy` contract with a `set_implementation` function that allows the contract owner to upgrade \n\n\nThe method that we will be covering utilizes the `replace_class` syscall to remove the need for a proxy pattern altogether. At the end of migration the contract utlizes an implementation class hash  with an upgrade method in it. This method assumes that the `replace_call` syscall will not be deprecated and the Proxy pattern in cairo0 will not be the dominant pattern for upgradeable contracts in cairo1.\n\nBefore proceeding with the tutorial, make sure you have the following dependencies installed.\n\n```bash\ncairo-lang v0.11.0\ncairo v1.0.0-alpha.6\nprotostar\n```\n\nYou can install `cairo-lang` with `pip`. We are using protostar but it is optional and can be replaced with any other similar tooling that you might prefer.\n\nThe code for the contracts used in this article is available at https://github.com/NethermindEth/0to1CairoDemo. Feel free to follow along!\n\n### Building and deploying the Cairo 0 contracts\n\nLet's start off by building the required Cairo 0 contracts.\n\n```shell\ncd cairo0\nprotostar build\n```\n\nDeclare both the `proxy` and the `cairo0resolver` that's built in the previous step.\n\n```shell\nprotostar declare ./build/proxy.json \\\n    --account-address $ACCOUNT_ADDRESS --max-fee auto \\\n    --private-key-path=../private --network testnet\n\nprotostar declare ./build/cairo0resolver.json \\\n    --account-address $ACCOUNT_ADDRESS  --max-fee auto \\\n    --private-key-path=../private --network testnet\n```\n\nHere, the `$ACCOUNT_ADDRESS` is the address of your wallet, and `./private` is the file containing your private key.\n\n\u003c!-- ```shell\nstarknet declare --contract build/proxy.json --account version_11_2\nstarknet declare --contract build/cairo0resolver.json --account version_11_2\n``` --\u003e\n\n\u003c!-- class hash 0xeafb0413e759430def79539db681f8a4eb98cf4196fe457077d694c6aeeb82\ntransaction hash for declaration above 0x6d72968648f4feab7776ac644137f7008b9b113980169c99fe90a3656852b54 --\u003e\n\nIf for some reason declare doesnt work from CLI, you can try ArgentX wallet's developer settings under `Settings -\u003e Developer settings -\u003e Smart contract development`, which provides a GUI for declaring your contract.\n\n![argent-dev](./argentx-dev-settings.png)\n\n\u003c!-- class hash 0x6cf18bc8305c6b2ce6d1954cf9a502fbd8fe4aac467bd89fb0682de4c077e6c\ntransaction hash for declaration above 0xe23e6ba05b95cc4e1836b08a64f107d16c2966f9b9343442dc33cf08410d70 --\u003e\n\nFinally, we deploy an implementation of the declared classes on chain via `protostar deploy`, which calls a UDC to deploy our contracts.\n\n```shell\nprotostar deploy $PROXY_CLASS_HASH \\\n--account-address $ACCOUNT_ADDRESS \\\n-n testnet --max-fee auto --private-key-path ./private \\\n--wait-for-acceptance \\\n-i $CAIRO0_RESOLVER_CLASS_HASH \\\n0x2dd76e7ad84dbed81c314ffe5e7a7cacfb8f4836f01af4e913f275f89a3de1a 1 \\\n$ACCOUNT_ADDRESS\n```\n\nThis deploys the Proxy contract and calls the `initializer` with the desired class hash to proxy to, which in this case would be the our `cairo0resolver` class.\n\nThe inputs provided via the `-i` flag specifies the class hash for the `cairo0resolver`, the selector for the `initializer` function, the length of the calldata, and wallet the address of the proxy admin respectively.\n\n\n\u003c!-- Some values used in the CLI below\n\nselector for 'initializer'  0x2dd76e7ad84dbed81c314ffe5e7a7cacfb8f4836f01af4e913f275f89a3de1a \n\nproxy declare at 0xeafb0413e759430def79539db681f8a4eb98cf4196fe457077d694c6aeeb82 \n\nUDC address 0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf\n\nimplementation class hash for cairo0resolver 0x6cf18bc8305c6b2ce6d1954cf9a502fbd8fe4aac467bd89fb0682de4c077e6c\n\nworking account address 0x1c15b60bc80306354cc68d83c1fc487b4b0b0e1540fe62c1df9aa3ae4ba396a --\u003e\n\n\n\u003c!-- ```shell\nstarknet invoke \\\n    --address 0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf \\\n    --abi ../UDC.json \\\n    --function deployContract \\\n    --inputs 0xeafb0413e759430def79539db681f8a4eb98cf4196fe457077d694c6aeeb82 0 0 4 0x6cf18bc8305c6b2ce6d1954cf9a502fbd8fe4aac467bd89fb0682de4c077e6c 0x2dd76e7ad84dbed81c314ffe5e7a7cacfb8f4836f01af4e913f275f89a3de1a 1 0x1c15b60bc80306354cc68d83c1fc487b4b0b0e1540fe62c1df9aa3ae4ba396a \\\n\t--account version_11_2\n``` --\u003e\n\n\u003c!-- transaction hash for above transaction 0x33017a6d35867256b06b34d4f4604e577dbe85c403b036617e13b1655c2c51\ncontract deployed at 0x000684167f946c40e4fe022e8af0bd6d17a18b04d0a0bed7826fecb891648222 --\u003e\n\n\n### Upgrading your contract\n\nBefore we perform the upgrade, let's perform some state changes on the contract. We can do this via invoking a the `set_starknet_id` function on the contract which will update the `resolver` variable to the specified value. You can do this either via `protostar invoke` or just using the Voyager provided function call interface.\n\n```shell\nprotostar invoke \\\n    --contract-address $PROXY_CONTRACT_ADDRESS \\\n    --function set_starknet_id \\\n    --inputs 10 2024 \\\n    --max-fee auto --private-key-path ../private \\\n    --network testnet --account-address $ACCOUNT_ADDRESS\n```\n\nIn voyager, you can invoke the function by going to https://goerli.voyager.online/contract/{CONTRACT_ADDRESS}#writeContract, where `CONTRACT_ADDRESS` should be replaced by the proxy contract address.\n\n![invoke-with-voyager](./voyager-contract-invoke.png)\n\nAfter the transaction is accepted, the state should be updated successfully.\n\nNext, let's prepare to upgrade our contract. As most Cairo tooling are still adding support to Cairo 1, we will be using the binaries from the Cairo repo directly as well as utilize the Starknet Cli.\n\nYou can reuse the account you used for the deployment of your previous contracts with protostar by editing your starknet account config, which usually resides in `~/.starknet_accounts`.\n\n```json\n{\n    \"alpha-goerli\": {\n        \"account_v11\": {\n            \"private_key\": \"${WALLET_PRIVATE_KEY}\",\n            \"address\": \"${WALLET_ADDRESS}\",\n            \"deployed\": true\n        }\n    }\n}\n```\n\nAs usual, build your Cairo contracts, but this time using the binaries from `Cairo v1.0.0-alpha.6`.\n\n```json\nstarknet-compile ./cairo1/cairo1resolver.cairo ./cairo1/cairo1resolver.json --replace-ids\n```\n\nNow, we can start declaring our Cairo 1 contract on chain.\n\n```shell\nstarknet declare --contract ./cairo1resolver.json --account account_v11\n```\n\nIf you have any issue declaring your Cairo 1 contract, you can check out [our article] on deploying your first Cairo 1 contract, which covers some of the problems you might face.\n\n\u003c!-- transaction hash for above transaction 0x3c490dc2a84ab9259b0c732b663b51106d31e868580681008b1a6d7749ad457\n\ncompile cairo1/cairo1resolver.cairo via cairo1 compiler and please add the steps for compiling etc here\nclass hash after declaration for cairo1/cairo1resolver.cairo 0x1d7ec1927b0bab67fdaea523906077c6f141eb68ca0e7b8c6403705d67fb1cb --\u003e\n\nFinally, we can now perform an upgrade via the proxy to the new Cairo 1 implementation.\n\n```bash\nstarknet invoke \\\n    --address $PROXY_CONTRACT_ADDRESS \\\n    --abi ./cairo0/build/cairo0resolver_abi.json \\\n    --function upgrade \\\n    --inputs $CAIRO_1_RESOLVER_CLASS_HASH \\\n        --account account_v11\n```\t\t\n\t\t\n\u003c!-- transaction hash 0x31ee06c302cc24719350ae248d31610478d6b0831804cd5bb27cec21fec16a3 --\u003e\n\nAfter the transaction is accepted by L2, you can now check if the implementation has been updated and the state is in tact as well to confirm that the update is successful! The proxy should now point to your Cairo 1 class and reading `resolver` should return you the same state as before without issues!\n\nWith this, you have successfully upgraded your Cairo 0.x implementation to Cairo 1!\n\n## Upgradable Cairo 1 contract\n\nWith the `replace_class` syscall, it is now possible to remove the need for a Proxy altogether. Now, to upgrade your contract, you can call the `upgrade` function which will call `replace_class` to replace the current class of your implementation with the provided class, effectively performing an upgrade.\n\nOur `cairo1resolver` class already implemented an `upgrade` function that utilizes `replace_class` for this. If you haven't implemented something like this yet, you might need to perform a upgrade for your proxy again to a class with this function implemented. It will look something like this:\n\n```rust\n#[external]\nfn upgrade(new_class_hash: core::starknet::class_hash::ClassHash) -\u003efelt252 {\n    replace_class_syscall(new_class_hash);\n    1\n}\n```\n\nLet's now proceed with calling the above `upgrade` function:\n\n```shell\nstarknet invoke \\\n    --address $PROXY_CONTRACT_ADDRESS \\\n    --function upgrade \\\n    --inputs $CAIRO_1_RESOLVER_CLASS_HASH \\\n    --account account_v11\n```\n\nAfter the transaction is accepted, you should now see that your proxy contract has been changed to a regular contract with an implementation class of `cairo1resolver`!\n\u003c!-- \nafter the above transaction is completed the contract at 0x000684167f946c40e4fe022e8af0bd6d17a18b04d0a0bed7826fecb891648222 has been changed from a proxy/implementation type to regular contract with an implementation class of 0x1d7ec1927b0bab67fdaea523906077c6f141eb68ca0e7b8c6403705d67fb1cb\n\ntransaction hash for above transaction 0x2d61b7f4b21d0ece5ba4f3abaa87d730112a7b33e19df2ec06e12b77b4db284 --\u003e\n\n\u003c!-- Final sentence --\u003e\nWith this, you now have a Cairo 1 contract that is upgradable as well!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNethermindEth%2F0to1CairoDemo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNethermindEth%2F0to1CairoDemo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNethermindEth%2F0to1CairoDemo/lists"}