i want to see the source codes when i deploy my canisters
Short version: the IC doesn’t store source code, only the compiled WASM module. So “seeing the source” isn’t something the protocol gives you, it has to be opted into by the deployer.
What you can get from any deployed canister today:
- Module hash via
read_stateat/canister/<id>/module_hash, certified. - Candid interface if the deployer included
candid:serviceas a custom WASM section (most tools do this by default). - Anything else the deployer put in custom sections (
icp:public <name>is readable by anyone,icp:private <name>only by controllers). Bounded by the 2 MiB certified-read response cap.
What’s missing: there’s no protocol-level field for “source repo” or “source code.” The WASM is on-chain; the .rs / .mo files are not.
The patterns people use to bridge this:
- Embed a pointer: a small public custom section with repo URL + commit hash + build command. Cheap and certified, but you’re trusting the deployer’s claim.
- Reproducible builds: publish source externally, anyone rebuilds, compares the resulting module hash to the on-chain one. This is the only approach that’s actually verifiable end-to-end. The hard part is making the build deterministic (pinned toolchain, no embedded timestamps, etc.).
- Verification services / registries: a third party rebuilds from claimed source and publishes an attestation. Shifts trust from deployer to verifier.
If you want this for your own canisters, the practical move is (1) + (2): embed {repo, commit} in a public custom section, and set up a reproducible build so anyone can verify the deployed hash matches. That’s about as close to “source visible on deploy” as the platform currently allows.
i see. so one can choose to not open source. is there a good reason to not open source or delay the open source? on icp i mean.
As long as you don’t open source, you can not verify the canister module hash, so in general you should always open source IMO.
But I guess some people want to protect their IP by not disclosing the source code. Another reason might be: security by obscurity. It is harder to break something you can not see.
I wonder if anyone has played around with Starlark as a scripting language within a runtime hosted by a canister.
Starlark maps very naturally to the same class of problem as consensus-based compute (but as a script rather than compiled). Deterministic source code, stored as text, evaluated by a trusted host runtime, with a deliberately limited capability surface.
If nobody’s tried this out on the IC before I think its worth a stab.
We can decompile Wasm and combine static analysis, formal checks, and AI-assisted semantic recovery.
This could become a practical source-less verification layer for ICP canisters.
Interesting idea. In some cases this might actually work quite well. Canisters would need to expose a download for their full WASM though (or you’d need to compile from source, at which point you’d already have the source).
I guess this comes down to a matter of convenience.
- Reverse engineering would not be very convenient and it wouldn’t be a perfect reconstruction in terms of readability.
- Reproducing builds from source and verifying the hash is more convenient and you have perfectly correct source code (if the hashes match). This is where we’re at.
- Some canisters could theoretically run a specialised scripting language (maybe Starlark) so the source code is literally in the same form as the original source while the interpreter is running it within the canister.
- Burn rate would be higher (scripting lanuages are less efficient)
- But convenience regarding verification could not be better
- This also means users could edit code in a browser and have it run onchain straight away (without having to trust/verify someone’s offchain compiler, deployment pipeline etc.)
- Super simple UX (if someone could get it to work)
Couldn’t this be done with QuickJS instead of Starlark?
Canisters can embed QuickJS, expose the exact JS source they execute, and publish the source hash plus runtime hash. That gives very convenient verification: users inspect the actual JS source, while the QuickJS host is audited/reproducibly built once.
Maybe, I don’t know enough about QuickJS. I’m sure there is a scripting language out there that will be perfectly suited to this though.
Starlark seems like a top choice because of its focus on determinism and also restricted surface for interfacing with the host system (I gather you’d have to write some sort of binding for the interpreter to have access to specific system calls, like transferring tokens). But that would be cleaner than having to disable a bunch of unnecessary functionality that would only serve to bloat the runtime (or so I’d expect).
QuickJS would win for language familiarity, but I suspect there would be problems with non-deterministic base library stuff, and probably various things that would need disabling.
Difficult to know without giving it a go, but my bet would be on Starlark being the one to focus on.

