# Canister integrity verification on chain is missing

**URL:** <https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353>\
**Category:** Developers\
**Created:** [January 18, 2022, 7:15pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353 "2022-01-18T19:15:09Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![northman](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/northman/32/3980_2.png) [@northman](https://forum.dfinity.org/u/northman)\
**Post date:** [January 18, 2022, 7:15pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/1 "2022-01-18T19:15:09Z")

</div>

When will it be possible to veriify the integrity of a smart contract on-chain?  
While the WASM hash can be checked off chain using DFX canister info, it presently cannot be checked on chain.

How is it possible to trust a smart contract when the controller could update the code to perform something not desireable without onchain detection?

Is it correct to say not having the ability to check the wasm hash on chain undermines composibility and security or is that an overstatement?

---

<div class="post-metadata">

**Author:** ![jorgenbuilder](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jorgenbuilder/32/22166_2.png) [@jorgenbuilder](https://forum.dfinity.org/u/jorgenbuilder)\
**Post date:** [January 18, 2022, 7:37pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/2 "2022-01-18T19:37:50Z")

</div>

I think that’s accurate. Verifying that a canister is blackhole controlled is one option. [https://covercode.ooo/](https://covercode.ooo/) is a good start on another approach where source code can be verified and audited, and verification status of a canister can be queried.

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [January 18, 2022, 7:58pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/3 "2022-01-18T19:58:01Z")

</div>

This would be a good place to see some activity relevant to this request: [RFC: Standardising how smart contracts expose state](https://forum.dfinity.org/t/rfc-standardising-how-smart-contracts-expose-state/8544)

---

<div class="post-metadata">

**Author:** ![PaulLiu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulliu/32/4701_2.png) [@PaulLiu](https://forum.dfinity.org/u/PaulLiu)\
**Post date:** [January 18, 2022, 8:13pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/4 "2022-01-18T20:13:46Z")

</div>

Developers have the freedom to decide whether states like wasm hash or cycle balance should be exposed or not.

I create the black hole canister exactly for this purpose:

[Introduce the black hole to help with canister status lookup + make them immutable](https://forum.dfinity.org/t/introduce-the-black-hole-to-help-with-canister-status-lookup-make-them-immutable/5755)

---

<div class="post-metadata">

**Author:** ![PaulLiu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulliu/32/4701_2.png) [@PaulLiu](https://forum.dfinity.org/u/PaulLiu)\
**Post date:** [January 18, 2022, 8:14pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/5 "2022-01-18T20:14:48Z")

</div>

Also, once outgoing HTTP call is implemented, one can use it to call the `read_state` API endpoint of the iC itself to get this info.

---

<div class="post-metadata">

**Author:** ![northman](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/northman/32/3980_2.png) [@northman](https://forum.dfinity.org/u/northman)\
**Post date:** [January 19, 2022, 12:47am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/6 "2022-01-19T00:47:49Z")

</div>

While blackholed and controllerless canisters are suitable for some applications, it does not address all. There are usecases that support the need to detect a canister has changed its code base on chain without the developer having to relinquish control. Canister consumers could review the code base if open-sourcce and then chose to execute or not the call to get service. A simple method like canisterHash() would be useful in my opinion. It would make configuration management of the services fabric much easier to orchestrate. I am a big fan of being able to provide telemetry about the smart contract state.

---

<div class="post-metadata">

**Author:** ![PaulLiu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulliu/32/4701_2.png) [@PaulLiu](https://forum.dfinity.org/u/PaulLiu)\
**Post date:** [January 19, 2022, 1:34am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/7 "2022-01-19T01:34:28Z")

</div>

> [@northman](#):
>
> There are usecases that support the need to detect a canister has changed its code base on chain without the developer having to relinquish control

Oh no, it is a typical misunderstanding of how blackhole can be used (the blame is on me choosing this name), but one can always have multiple controllers on a canister, with blackhole being one of them would be good enough to programmatically detect canister hash changes.

---

<div class="post-metadata">

**Author:** ![northman](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/northman/32/3980_2.png) [@northman](https://forum.dfinity.org/u/northman)\
**Post date:** [January 19, 2022, 3:24am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/8 "2022-01-19T03:24:16Z")

</div>

So maybe I can rephrase to ensure my understanding.

**Canister A** is a canister with some critical code whose hash we want to check on-chain.

A second canister called **Canister B** is created and made a controller of **Canister A** in addition to the existing controller. That way the existing controller can still do code upgrades as the canister is not immutable.

**Canister B** can expose a public function to show the hash of **Canister A**.  
**Canister B** can query the hash of **Canister A** because it is also a controller of **Canister A**.

Am I on the right track?

The downside is that the public showhash() function could be implemented differently by each canister vs having it built in to the base canister management API. There is also a cost of having to create and maintain the **“watcher”** canister. The upside is this can be implemented now.

Thanks for clarifying. The title - Blackhole **and making them immutable** threw me off a little.

---

<div class="post-metadata">

**Author:** ![PaulLiu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulliu/32/4701_2.png) [@PaulLiu](https://forum.dfinity.org/u/PaulLiu)\
**Post date:** [January 19, 2022, 3:30am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/9 "2022-01-19T03:30:01Z")

</div>

Yes, you summarized it well. I’d add that the downside is “Canister B” may not be trustworthy to show the hash to a 3rd party. This is where using blackhole can help.

---

<div class="post-metadata">

**Author:** ![bjoern](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/bjoern/32/2100_2.png) [@bjoern](https://forum.dfinity.org/u/bjoern)\
**Post date:** [January 19, 2022, 5:52am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/10 "2022-01-19T05:52:19Z")

</div>

> [@northman](#):
>
> While the WASM hash can be checked off chain using DFX canister info, it presently cannot be checked on chain.

Just wanted to mention that the ability to check for a controller “on chain” is on our backlog.

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [January 19, 2022, 7:52am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/11 "2022-01-19T07:52:53Z")

</div>

> Developers have the freedom to decide whether states like wasm hash or cycle balance should be exposed or not.

My understanding is that wasm hash is public state and should be queryable by anyone, controller or not. (Although in practice, getting the wasm hash is easier done via ingress calls, as only controllers can currently call the IC method canister\_status to get the hash.)

But more generally, when you say that developers have this freedom, are you referring to their choice to set the blackhole canister as one of their canister’s controllers?

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [January 19, 2022, 7:54am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/12 "2022-01-19T07:54:19Z")

</div>

Will checking for a canister’s wasm hash on-chain (without the caller needing to be a controller) also be part of that?

Both a canister’s controllers and its wasm hash are “public state” that any user can query for via [ingress calls](https://smartcontracts.org/docs/interface-spec/index.html#state-tree). In fact, I think there’s only those two.

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [January 19, 2022, 8:06am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/13 "2022-01-19T08:06:50Z")

</div>

> [@northman](#):
>
> There are usecases that support the need to detect a canister has changed its code base on chain without the developer having to relinquish control.

This is actually quite deep and I suspect will become increasingly important in the months and years to come.

IIUC the solution proposed here is to add the blackhole canister as a controller to the canister of interest, without removing the original developer as a controller. The blackhole canister is immutable (i.e. its only controller is itself) and it’s open source with only 30 lines of code, so it can be trusted to return the correct wasm of the original canister. Does that sound accurate?

* * *

What if the developer pushes a malicious update to the dapp canister that isn’t reflected in their github?

Sure, if you query the blackhole canister for the wasm hash of the dapp canister, it will differ from the hash of a wasm built from the source on github. But who will check? What if a couple of users accidentally call the malicious dapp canister before remembering to check, and as a result loses some funds?

I think there one day may need to be some open internet service that sits between clients and dapps, whose job is to verifiably build a dapp’s wasm from source (ideally stored on-chain but could also fetch from github once canisters can make HTTP requests), take the hash, call the blackhole canister for the live dapp canister’s wasm hash, and compare the two. If they’re the same, then proxy the call to the dapp; otherwise, return an error to the user. Of course, this service itself needs to be an immutable canister. I guess this is what [Cover](https://covercode.ooo/) is doing?

---

<div class="post-metadata">

**Author:** ![oggy](https://avatars.discourse-cdn.com/v4/letter/o/df705f/32.png) [@oggy](https://forum.dfinity.org/u/oggy)\
**Post date:** [January 19, 2022, 8:38am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/14 "2022-01-19T08:38:15Z")

</div>

> [@northman](#):
>
> There are usecases that support the need to detect a canister has changed its code base on chain without the developer having to relinquish control. Canister consumers could review the code base if open-sourcce and then chose to execute or not the call to get service.

This is susceptible to time-of-check-time-of-use bugs; the canister code could in principle change under your feet between the time that you check the hash, and the time where your call is performed (obviously, the attacker would have to time this right). One way of addressing this would be to allow callers to pin a call to a canister hash, but IC doesn’t currently support this, and I don’t think it’s on the roadmap - if there’s wider interest from the community, this can obviously change.

We also have some documentation on how to verify canister integrity here:

> **[Smart Contracts on the Internet Computer](https://smartcontracts.org/docs/developers-guide/tutorials/reproducible-builds.html)**
>
> Build smart contracts and dapps 100% on-chain on the Internet Computer, the world's fastest and most powerful open-source blockchain network

---

<div class="post-metadata">

**Author:** ![akhilesh.singhania](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/akhilesh.singhania/32/487_2.png) [@akhilesh.singhania](https://forum.dfinity.org/u/akhilesh.singhania)\
**Post date:** [January 19, 2022, 9:29am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/15 "2022-01-19T09:29:24Z")

</div>

@bogdanwarinschi , @bjoern , and I have been discussing the RFC and we are going to start working on the spec changes.

---

<div class="post-metadata">

**Author:** ![JensGroth](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jensgroth/32/2006_2.png) [@JensGroth](https://forum.dfinity.org/u/JensGroth)\
**Post date:** [January 19, 2022, 10:02am UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/16 "2022-01-19T10:02:03Z")

</div>

A query call can also be issued as an update call, so it is possible to read a wasm hash on-chain with the read\_state call you linked to.

---

<div class="post-metadata">

**Author:** ![PaulLiu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulliu/32/4701_2.png) [@PaulLiu](https://forum.dfinity.org/u/PaulLiu)\
**Post date:** [January 19, 2022, 4:02pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/17 "2022-01-19T16:02:16Z")

</div>

> [@jzxchiang](#):
>
> But more generally, when you say that developers have this freedom, are you referring to their choice to set the blackhole canister as one of their canister’s controllers?

Yes.

> [@jzxchiang](#):
>
> I think there one day may need to be some open internet service that sits between clients and dapps

I believe that is one of the things SNS is meant to do. [Open Governance canister for SNS | Design proposal](https://forum.dfinity.org/t/open-governance-canister-for-sns-design-proposal/10224)

Correction: I meant not exactly the same “check hash before calling canister”, but more generally to ensure code update goes through security reviews, etc.

---

<div class="post-metadata">

**Author:** ![northman](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/northman/32/3980_2.png) [@northman](https://forum.dfinity.org/u/northman)\
**Post date:** [January 19, 2022, 8:12pm UTC](https://forum.dfinity.org/t/canister-integrity-verification-on-chain-is-missing/10353/18 "2022-01-19T20:12:19Z")

</div>

I thought a video on the issue might be useful.

[![](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/2X/3/318012c4f724afaf94639b39eafe5745d871f70a.jpeg "ICP WASM Module Verification") ](https://www.youtube.com/watch?v=HeVzYhRVlWw)
