Derived Canister IDs

I wanted to pop this back up to the top of the discussion queue as it was previously buried in a Psychedelic authored post. Especially with all the talk of canister based wallets this becomes important again. If we can derive alt principles for our canisters we can provide more privacy for canister based wallets in much the same way that II does this for user principles. The wallet dapp would be able to collate data from different services as untraceable different principals and do the collation for the user in the wallet dapp canister.

Our Proposal: Right now, subaccounts are being derived at the application level. We propose adding a protocol level mechanism for canisters to derive more IDs (with or without the need to deploy more canisters), similar to the way that new principals can be derived and managed by wallets with BIP44 & BIP32.

We propose this is done by allowing a canister to make inter-canister calls with different principal IDs. Let’s say canister A is making a call to canister B, when canister B runs ic::caller() on A, we could get different Principal IDs for canister A.

To do so we propose introducing a new IC system api called ic0.call_set_derivation in the WASM runtime, which could be used by canister A, to indicate it wants to make the call to canister B using its different account. The api call will become a member of the already existing IC system api calls:

ic0.call_new :                                                              // U Ry Rt H
  ( callee_src  : i32,
    callee_size : i32,
    name_src : i32,
    name_size : i32,
    reply_fun : i32,
    reply_env : i32,
    reject_fun : i32,
    reject_env : i32
  ) -> ();
ic0.call_on_cleanup : (fun : i32, env : i32) -> ();                         // U Ry Rt H
ic0.call_data_append : (src : i32, size : i32) -> ();                       // U Ry Rt H
ic0.call_cycles_add : (amount : i64) -> ();                               // U Ry Rt H
ic0.call_cycles_add128 : (amount_high : i64, amount_low: i64) -> ();      // U Ry Rt H
ic0.call_perform : () -> ( err_code : i32 );                                // U Ry Rt H

This would be easy for developers to understand from other ecosystems, leave us with only a single ID to deal with, clean up client side code, and be very useful for canister based wallets once we have tECDSA


It seems like the original thread turned out to be mostly about this anyway, and still contains good ideas and info.

Tagging @PaulLiu, @roman-kashitsyn, and @bjoern since I thought they contributed some important points last time.

1 Like

As written in the other thread, as long as we are fine with using something like the “derived principals” – like hash(principal || derivation) – then this should be doable on the protocol layer if it’s helpful on the application side.

1 Like

This is brillaint

I just wanted to follow up here with linking this thread,
As I think there is a need on the ic for this sort of canister.

@infu and I wrote up a lite paper on personal canister wallets. Currently called Neutron. If we have derived canister ids we can provide similar security to internet identity from these wallets.

With derived canister ids we can do aggregations across different services via different principals to resist user correlation and maintain privacy.

I’d love feed back and would love to see where we could slot derived canister ids on the road map.