While developing a project on the Internet Computer, there are several crucial design decisions to make. Among these decisions, the choice of canister architecture emerges as one of the most fundamental. So far, we’ve seen these prevalent canister patterns:
- Single Canister Pattern: In this pattern, the entire dApp operates from a single canister, which contains all the application’s operations and functionalities.
- Multi Canister Pattern: This approach divides the dApp’s functions among multiple, specific-purpose canisters. Although the canisters are numerous, their number remains finite and pre-determined.
- Personal Canister Pattern: This design pattern includes the automatic generation and deployment of individual canisters for each user at registration. Alongside these, several specific-purpose canisters are deployed. Essentially, each user has a personal canister, supplemented by numerous functional canisters.
Benefits of the Personal Canister Framework
We’ve seen a number of dApps (such as OpenChat, Anvil, AstroX, Ego, and Mora) that employ the Personal Canister Pattern. The benefits of this framework appear to be:
- Improved Scalability: With this method, the application’s scalability is primarily dictated by the capacity of the subnet, not the limits of individual canisters. This yields enhancements in usable memory, transactions per second, and the quantity of inter-canister calls that can be managed.
- User Empowerment: Users automatically acquire the capabilities of the canister, including on-chain storage/computation, multi-chain wallet, and upgradeability.
- Enhanced Peer-to-Peer Communication: This framework enables superior C2C interactions and eliminates the need to communicate through a main canister.
- Developer Focus: Developers can concentrate on protocol development, bypassing the tendency to mimic Web2 approaches.
While I’m incredibly enthusiastic about this approach, I’m not certain that I’ve comprehended its full potential. Currently, I find myself with more questions than certainties, leading me to kickstart this discussion to gather other developers insights.
- Are you as excited as I am about this pattern? Do you also envision this pattern becoming predominant in IC-based development?
- Should users have individual personal canisters for each dApp, or should we amalgamate dApp functionalities into a single personal canister?
- How would we upgrade such a dApp? How can we ensure all canisters are synchronized to the same version? How should we design a registry canister?
- How can we monitor such a dApp? Is there such an entity as a monitoring canister?
- What are the best practices for C2C communication? Are there patterns that we should avoid?
- How do we manage the costs of user acquisition? How do we prevent spamming and Sybil attacks?
If you’re interested in exploring this subject further, here are some resources I’ve identified:
Feel free to add more resources, by posting in this topic and I’ll make sure to add them to the list. Notably, I’m looking for a Motoko repository that uses this pattern.
Thanks for checking this out, and any input you’ve got would be awesome!
It’s great to see your interest in the Personal Canister Pattern for Internet Computer development. As the creator of B3Wallet, which utilizes the Personal Canister Framework, I can share some insights based on my experience.
- Excitement and Predominance: I’m absolutely excited about this pattern and its potential in IC-based development. It offers significant benefits in terms of scalability, user empowerment, and efficient peer-to-peer communication. I believe as developers explore its advantages, it has the potential to become a popular choice for various applications.
- Individual vs. Consolidated Canisters: The decision to use individual personal canisters or consolidate functionalities depends on the specific use case. For B3Wallet, having individual personal canisters allows each user to have their own secure space, including a multi-chain wallet. It enables personalized upgrades without affecting other users. However, in some cases, consolidating functionalities into a single canister might be more suitable, especially for simpler applications.
- Upgrading and Synchronization: Upgrading a dApp with personal canisters requires careful planning. Having a well-designed registry canister can help manage versioning and ensure all canisters are synchronized to the same version. Additionally, automated testing and deployment strategies can assist in seamless upgrades.
- Monitoring: While there’s no specific “monitoring canister,” integrating monitoring mechanisms within your dApp is essential. You can design monitoring functionalities to track canister health, performance, and user interactions. This helps identify any issues and ensures smooth operations.
- C2C Communication: Best practices for C2C communication involve using efficient message passing and inter-canister calls. Avoid overloading canisters with unnecessary data and implement proper error handling to maintain robust communication.
- User Acquisition and Security: Managing user acquisition costs and preventing spamming and Sybil attacks can be achieved through user authentication mechanisms. Implementing identity verification processes can ensure genuine users access personal canisters.
I hope these insights are helpful in your exploration of the Personal Canister Pattern. The resources you provided are valuable references, and I encourage you to keep exploring this pattern to unlock its full potential.
If you have any further questions or need more details about my experience with B3Wallet, feel free to ask. Happy coding and best wishes for your IC-based development journey!
Consider interoperability at the protocol level instead of requiring everyone to run the same canister version. And be sure to have implement protocol backwards compatibility allowing users to upgrade at their own pace.
A fully agent centric protocols first approach means you have no control over clients. An upgrade to the SMTP or MIME protocols don’t force you to upgrade your email program. Not in quite some time at least.
An “app store” for personal IC apps would be needed for users to self manage.
I have already designed B3Wallet to follow this principle of protocol interoperability. Users won’t be forced to upgrade immediately, but we recommend everyone to upgrade regularly for the latest security updates.
With B3Wallet’s thoughtful design, we prioritize user autonomy, enabling them to choose when to upgrade while ensuring their transactions remain secure. Our commitment to protocol interoperability enhances the user experience and empowers them to engage with the Internet Computer ecosystem seamlessly.
Nice! Is the image from the wallet app?
Yes, you can try the B3Wallet.live.
But the bitcoin-testnet API gets disabled by Dfinity right now.
- Single Canister Pattern: Primarily I’ve only used single canisters for MVPs, and often times multiple canisters can be overkill/can be added later.
- Multi Canister Pattern: I personally like this, it remains easily upgradeable while the app grows. It’s not so difficult to scale an entire canister either. I think its better for free services because you don’t need to consider registration costs with canister per user.
- Personal Canister Pattern: I’m sure there are scenarios where this is preferred, here is my reasoning why I don’t always opt for it. Let’s say your app immediately scales to 1,000 users, I’m not sure I’d want to deal with managing 1,000 canisters until further down the road. Also depending on the data stored in the canister, isn’t it possible that even these would eventually need to scale?
How do we prevent spamming and Sybil attacks?
This is interesting to me in the personal canister pattern, you could potentially have 1,000s of canisters to remedy solutions for, and you’d also need to add cycles to them in the case of a cycle drain attack. Maybe a design solution worth considering is making these canister Ids as private as possible to make it hard to do this.