Is there a way right now to validate or ensure a version of a canister being called?
I was thinking about a scenario where I ONLY want to call the canister that has a specific binary running, not any ‘updated’ versions, or just fail/error.
In other blockchains, the immutability allows for the use of a smart contract without it ever being changed. This is inflexible but creates this stability and trust that things can’t change unless you update your dapp to use a different smart contract.
Unless ownership of the canister is completely given up, there is a problem of trusting the thing you are calling is what you expect.
I was just wondering if there was a way now/in the future to restrict a canister call based on canister version/canister binary hash.
Currently this is only possible for external users (i.e not inter-canister calls) as far as I know. As an external user you can access public metadata via the read_state API. This includes the module hash.
That solves most of the problems but in theory, the time between accessing the module_hash and making an external api call to a function, the module could change right? Very unlikely but just thinking out loud
You could add an explicit argument for version number or binary hash to your functions. The caller would supply the argument and the canister would check the argument matches its version/hash.
Fair point, but a use case I’m trying to figure out if if the canister is not trusted. In theory the canister can be updated to not have that check or it might not be there at all. It would probably have to be an IC protocol check which sounds like doesn’t exist
There is a ‘black hole’ canister at e3mmv-5qaaa-aaaah-aadma-cai. If it reports that it is the only controller of a canister, then that canister is immutable. You can use that as a programmatic constraint.
Even users can’t be sure. Because code hash could have changed between the time you checked it (via dfx canister info) and the time you make the call. Even if you check after you make the call, and see the code hash was the same, it still can’t prove anything – because some one could have done an upgrade to change code from version A to B and then back to A.
Sure, making canister immutable is one way to go about it. But other than those with trivial implementations (e.g. the blackhole canister itself), real apps do need regular upgrades, and for good reasons like maintenance/features/bugfix, etc.
This is why we build LaunchTrail to help.
A developer can first deploy their own LaunchTrail canister, set it as immutable, and then use it deploy/upgrade/manage other canisters. Anything that goes through LaunchTrail literally leaves “a trail”, which gives a chance for the public to verify (and for the developer to prove) what has happened and what is going to happen, because LaunchTrail can set code upgrade as a delayed action that will only take place at a future time.
Back to the original question, if a canister was deployed through LaunchTrail, its users (including other canisters) can verify the following:
The canister is running the code hash it claims to be running.
The canister’s code hash history since its creation is fully auditable.
The canister’s code hash is either not going to change in XX days, or scheduled to change at some point.
As a corollary, if the canister’s code hash history is verified to match source and the source is trusted to behave correctly, then the canister’s current state (data stored in there) and behavior (as prescribed by code) can be trusted. So another canister can safely rely on this one.
Of course it still depends on the developer to use LaunchTrail correctly and hence prove themselves to the public. But at least this is entirely possible on IC today, and developers should start doing it!
I would just like to say I LOVE the Internet Computer community.
Everyone is working on something.
Essentially everything is open source.
There is always something new to learn