Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: re-introduce __default__ entrypoint #6170

Open
enitrat opened this issue Aug 8, 2024 · 6 comments
Open

feat: re-introduce __default__ entrypoint #6170

enitrat opened this issue Aug 8, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@enitrat
Copy link
Contributor

enitrat commented Aug 8, 2024

Feature Request

In Cairo Zero, we had the __default__ entrypoint. When you tried to invoke an entrypoint that didn't exist in the contract class, your call could be redirected to this __default__ entrypoint and you could handle it as wanted.

The main motivation for this is to re-introduce the transparent proxies and beacon proxies pattern. Consider an application where you deploy a contract for your users. Eventually, as your needs grow and you add features, you will need to upgrade potentially all deployed instances by users; which will require a manual action from your users. Then, you're forced to keep compatibility with older versions, which rapidly becomes a pain.

With beacon proxies, you could simply create a pattern where all calls are delegated to an external class, that can be updated in a single contract, by using the __default__ entrypoint.

@enitrat enitrat added the enhancement New feature or request label Aug 8, 2024
@gaetbout
Copy link
Contributor

gaetbout commented Aug 8, 2024

+1 to this

@orizi
Copy link
Collaborator

orizi commented Aug 12, 2024

doesn't replace_class_syscall solve this usecase? or did i misunderstand the usecase?

@enitrat
Copy link
Contributor Author

enitrat commented Aug 12, 2024

No, replace class allows replacing the class of one single contact at a time.

We're in the situation of using a pattern called the beacon proxy that allows you to deploy a new implementation contract and upgrade all proxies simultaneously.

Example use case: you're deploying contracts for an applications where you are deploying one contract for each entity.

As your application gets new features, you need each entity to support the new features. So you might need to add entrypoints, modify some behaviors, add some storage vars, etc.

Currently the only possibility is to have an owner contract that would call replace_class on ALL the deployed entities. If you have 50 thousands contracts deployed, you would need to manually update these 50k contracts

With my proposal, entities would simply make a library call to a class that is known to be the most up to date. You only need to change, in one single location, the hash of the latest class

@iliav-starkware
Copy link

@enitrat if you had get_class_hash_at, couldn't you have a distinguished upgradable instantiation of it, and point all the other contracts to it? (Perhaps I completely misunderstood your problem though 😱)

@petarcalic99
Copy link

petarcalic99 commented Aug 14, 2024

Hello, I am sorry but I'm not sure i understood your proposal @iliav-starkware, but here is another description of the issue https://docs.openzeppelin.com/contracts-cairo/0.15.0/upgrades#proxies_in_starknet
Its true than in most cases replacing the class hash by an admin might suffice but in some cases a general proxy is needed and more elegant, like for the use case of beacon proxies. The fallback would make the implementation more simple.

@enitrat
Copy link
Contributor Author

enitrat commented Aug 14, 2024

@iliav-starkware using get_class_hash_at or reading a storage variable in a registry contract is similar, but doesn't solve the main issue.

TLDR: __default__ ensures transactions don't fail if an entrypoint is not found, and you can define arbitrary logic in case that entrypoint is not found. By only having the __default__ entrypoint in your contract, in which you library call to a specific class, you make sure that if you update that class, the upgrade is automatically reflected in all contracts

Let me know if the problem is clearer with the concrete example of Kakarot.

Each EOA in the Kakarot system is represented by a unique starknet contract, such that 1 EOA = 1 Starknet Contract. As such, everytime an account is created within Kakarot, an Account Contract is deployed on Starknet.

When we update Kakarot, we often make breaking changes to how these account behave: adding paymaster mechanism, optimising calldata, caching values in the account's storage, creating new entrypoints to access specific informations, etc.

Everytime we make such a change, we break the existing compatibility of accounts with Kakarot. If we introduce a new entrypoint, or change the signature of an entrypoint, then the old account becomes unusable within Kakarot, as calling this entrypoint would make the transaction revert.
As such, we must manually update all accounts deployed withing Kakarot. Today, that's more than 50k+ contracts, that we would need to update one by one, calling replace_class. Of course, this imposes a security risk, as to upgrade these accounts, we need admin rights on them.

What the proposal achieves is the ability to redirect any call to a contract's entrypoint to a __default__ entrypoint instead of reverting. This __default__ entrypoint can be programmed to execute a library_call to a class, or another contract_call or anything.

In our case, this means that if inside our __default__ entrypoint, we simply forward the call to the class in the registry, updating one single registry contract with the new account class to use will update the logic of all deployed accounts. We can add entrypoints, remove entrypoints, change the logic at will, and never worry about having a manual upgrade process on 50 - 100k accounts that might fail, takes time and requires downtime, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants