Canister controller and cycle balance need to be public

I can’t think of any good reason why these 2 pieces of data are private. Canister controller is already public off-chain, so it should be public on-chain (through ic-management).


According to the NNS AMA, the system doesn’t assume that Neuron info should be public.

I suppose we could debate this for a while, but how about this - I propose that these fields be public:

  • cached_neuron_stake_e8s - we can already calculate to an accuracy of +/- 1 e8s from voting_power
  • maturity_e8s_equivalent - no good way to calculate, nothing confidential here. also there are accounting usecases that would be simplified with this being available
  • followees - maybe slightly more confidential, but needs to be public for transparency
  • neuron_fees_e8s - nothing confidential

What are your thoughts on why the cycle balance should be public?

Agree. I’d like to add the module hash should be public too.

If we’re interacting with a service, we should know how much runway it has left. If it’s a NFT canister that only has 1T left, I wouldn’t be comfortable storing long term assets in it.

Also, why should it be private?


If privacy is the concern, than at least give developers the ability to make cycle balance/controller available publicly.

I agree re: neurons too - cached stake not being available to non-controllers doesn’t seem smart as we can calculate manually as per @wang’s msg OR we can just lookup the neuron account and see the balance in the ledger.

Followees may be a privacy thing I guess, but at least allow users to specify if they can make this publicly available too.

I would prefer default public, optional private. Then, it’s up to developers to explain to their users why things are private.


Yup agree with that too

If you want to feel comfortable storing an nft, the cycles balance isn’t enough you’d have to have the source code to make sure the cycles couldn’t be transferred out to someone and also you’d need to make sure that the contract can only be changed by a sufficient decentralized vote , or you’d have a set up where you spin up and fund your own nft canister once the standards come . So for those cases where the source is known to you there can be a public canister function that gives the current cycles balance and you can certify that it is , but the ic is not just a platform for open tokenized dapps, it’s the global-computer that’s meant to host the every kind of the software, not every business wants the world to know how much money they are making. wallets, cycles will be a stable coin, I want to keep my money-count with my self. the blockchain itself certifies the global cycles count if you are thinking bout that.

I do think there should be a way for a canister-controller to let non-controllers certify the canister-source with the hash and certify the controller but i think there might already be a way to do that with the legations.

Edit: controller and module_hash are public, see below.

Agreed that cycle balance is just one of the many requirements for asset storage.

Using native cycles as a medium of exchange/unit of account is cumbersome, so I imagine wrapped cycles will fill that role. Whether these wrapped tokens have privacy features or not is a separate concern.

the ic is meant for personal code systems as well. using native cycles as a medium of the change is the most straight-forward way to do it. there will be standards that catch on that let people send and get cycles from personal canisters with custom flows of some sort.

I am testing my self and I see the controllers and the module_hash are public.

  • Ledger canister:
    • module_hash: 8e478353381b52ad3926601fc730982aa8886b78a089ddd6d184c9b5641d2d7a
    • controllers: [[0, 0, 0, 0, 0, 0, 0, 3, 1, 1]] // r7inp-6aaaa-aaaaa-aaabq-cai
  • dscvr: h5aet-waaaa-aaaab-qaamq-cai:
    • module_hash: 2664385b7ad001123d8cea1f7147fad005d012116139787d9054b2f3a62718ec
    • controllers: [[0, 0, 0, 0, 0, 48, 0, 20, 1, 1]] // g6mnv-cyaaa-aaaab-qaaka-cai

Summary of what data is available and how. Everything public off-chain should be public on-chain as well!

Data Public, off-chain Public, on-chain Controller, on-chain
Subnet :white_check_mark: :no_entry_sign: :no_entry_sign:
Controller :white_check_mark: :no_entry_sign: :white_check_mark:
Status :white_check_mark: :no_entry_sign: :white_check_mark:
Module Hash :white_check_mark: :no_entry_sign: :white_check_mark:
Cycle Balance :no_entry_sign: :no_entry_sign: :white_check_mark:
CPU/Mem :no_entry_sign: :no_entry_sign: :white_check_mark:

What do you mean that the controller and module hash are only public off-chain? The path: canister/canisterId/controlller in the system state tree which we can call and certify the sponse , gives the controller of a canister. ?

Is the state tree available within a canister? How do I access it with Motoko or Rust?

1 Like

I think there can an easy opt-in solution to make canister status public, without modifying the current IC behavior:

  1. Create a “blackhole” canister, with an exported interface canister_status.
  2. The method just calls ic0.canister_status to lookup status of a given canister id.
  3. If anyone wants to make their canister status public, just add “blackhole” to the controller list.
  4. But that wouldn’t be safe if “blackhole” can be changed. To make it safe, “blackhole” should have its controller field removed (or set to itself).

What do you think? @wang

1 Like

@wang Check this out GitHub - ninegua/ic-blackhole: Once a canister sets its only controller to a black hole, it becomes immutable and more!

With the blackhole canister, you can check the status of any canister that has set one of their controllers to the blackhole canister. For example to see the status of the blackhole canister itself:

dfx canister --network=ic --no-wallet call blackhole canister_status '(record { canister_id = principal "e3mmv-5qaaa-aaaah-aadma-cai"; })'
  record {
    status = variant { running };
    memory_size = 304_221;
    cycles = 2_126_143_362_964;
    settings = record {
      freezing_threshold = 2_592_000;
      controllers = vec { principal "e3mmv-5qaaa-aaaah-aadma-cai" };
      memory_allocation = 0;
      compute_allocation = 0;
    module_hash = opt blob "!\0c\f9A\e5\caw\da\ac1J\91Qt\83\ac\17\12dR~=\0dq;\92\bb\95#\9d}\e0";
1 Like

Thanks Paul. There is a need for a dead/unowned principal but having to remember e3mmv-5qaaa-aaaah-aadma-cai isn’t very ideal, I think aaaaa-aa would be better for that usecase.

I’m still in favor of public by default because I don’t think most devs will bother to opt-in, especially if the process for adding multiple controllers is complex.

Perhaps building this into dfx would be better? Add a flag to dfx.json like public_status: true which automatically adds the blackhole controller.


hmmm, i see, i think controller and module_hash should be able to be seen within another canister if it is public from the outside.