Tackling CertifiedData in Motoko

I think I though of a decent use case:

Canister A hods some state that is important to a decision on Canister B. Canister B could query Canister A for that state during an update query, but that will result in the cycle cost of a XCanister Call and a round trip for waiting for consensus.

Instead it would be nice if A could push the certified data to B once and then the client could deliver the certificate with the update call with a witness and validate any number of pieces of data on A without the XCanister call.

Example: A is a ledger of Tokens X. B awards a Token Y if you burn tokens X. A can update B on the root and all burns → mint can be executed without a XCanister call.

Maybe a bit contrived, but sure, I’ll take it. Now we just need volunteers to write the corresponding libraries for Motoko :slight_smile:

What are those for the certificate?

I think it is cbor encoded so we’d need to parse a subset of cbor values. What are the fields and types?

What crypto library do we need for validating the signature?

See the CDDL spec. CBOR tags, arrays, records and bytes.

Oh, right, you still need to validate the signature. That would require an implementation of BLS. Probably not fun in pure Motoko… maybe we should bet on developer-accessible FFI.

Thank you for the link!

FFI means being able to reference and call rust functions from our motoko code right? That would be game-changing.

1 Like

I am building a proof of concept Motoko canister that serves a dynamic HTTP asset and certifies it, including CBOR encoding etc.:

Code at https://github.com/nomeata/motoko-certified-http

It’s still buggy (https://ce7vw-haaaa-aaaai-aanva-cai.ic0.app/ doesn’t work) and I am out of time for today; I’ll create a new post once it actually works. But at least it works already on https://ce7vw-haaaa-aaaai-aanva-cai.raw.ic0.app/.


Works now, see Certified Assets from Motoko (PoC/Tutorial)


@nomeata @skilesare @claudio

I have a question about using Certified Variables and I think its relevant to this thread.

I am trying to understand how Canister Signatures work so that I may use them in Motoko to create a canister-controlled neuron, as described by @bjoern here.

I just finished watching @nomeata’s video presentation Inside the Internet Computer | Certified Variables and one question I have is how this subnet certified data will be handled in the future if a canister migrates from one subnet to another.

Specifically, if I create a canister-controlled neuron that can only be controlled via certified data from a given subnet, do I run the risk of losing control of that neuron in the future if my canister migrates to a different subnet?

1 Like

I don’t think you can do that quite yet. But we are close. Watch the skies! You’ll need to use a t-ecdsa signature I think. I don’t think canister signatures are going to let you control a neuron.

1 Like

I suspected as much, but I’ve been told differently and I wanted to do my due diligence.

Edit: For clarification, do you not think it can be done at all or do you think this is only a limitation for Motoko?

I think they limit canisters from holding neurons on purpose. The t-ecdsa routes around that. Seems like it will be a silly restriction once we have t-ecdsa, so hopefully we can have it removed. I think the canister signatures are used for delegations, so maybe you could delegate to a canister your ownership of a neuron…but you’d need some way to prove you’d destroyed the private key.

I agree.

Not sure I follow. If I eventually remove the controller of the canister, or hand control to the DAO wouldn’t that be verified by checking the canister’s controller list?

@skilesare here is the process that @bjoern provided to me on Twitter.

Ha! Ok…so that is interesting. I’d be happy to outline that out a bit here.

I’m clearly missing something here. A canister can sign a root, but I don’t think it can sign data. Wouldn’t it need to sign the transaction? (Maybe the key here is that all that needs to be signed is a transaction hash.) If that is the case then you aren’t really signing a Merkle tree, you are just signing a root that isn’t a root, but a hash of a transaction. Maybe @bjoern can give some clarity.


  1. Send Transaction hash and candid to the canister. Have the hash written to the certified data.
  2. Have the canister submit a query via the new HTTP interface to get the signature
  3. Do a second HTTP call to send the call to the management canister and the signed hash to the IC.

I wish I’d thought of that before because we could have been doing this manually for a while…now with HTTP requests, we can automate it.

1 Like

The canister would create the ingress message and would put the request id into a Merkle tree structure as described in the section on canister signatures. In a subsequent query call to that canister, one can request the signature on the root of the Merkle tree, and the canister can also return the path in the Merkle tree. Together, those form the “canister signature”. This is exactly what we do in Internet Identity; well, we “sign” a delegation not an actual request id, but that doesn’t really matter, just do what II does but “sign” the request id instead.

That said, as @skilesare pointed out, canister signatures (and the tECDSA feature as well) together with the HTTP request feature make the restriction that canisters cannot hold neurons somewhat artificial. So maybe there is a discussion to be had (maybe first in a dedicated thread here in the forum, and maybe that could lead to an NNS proposal) about lifting that restriction.

1 Like

Thanks @bjoern, I have a few follow-up questions:

Do you know if I risk losing control of the neuron in the scenario described above?

Do you have a reference for doing this? I’m still learning the ins/outs of Motoko. I thought only external actors could create ingress messages.

So does this mean that the canister itself would not be submitting the neuron management calls to the NNS? I would need some authorized third party to retrieve these variables and then pass them to the NNS indirectly?

That is not a risk. Let us look at the spec, in particular the part that defines the “public key” for canister signatures:

The BIT STRING field subjectPublicKey is the blob |signing_canister_id| · signing_canister_id · seed, where |signing_canister_id| is the one-byte encoding of the the length of the signing_canister_id and · denotes blob concatenation.

The key only depends on the signing_canister_id and a canister-chosen seed. No information about the subnet is used. In fact, we will be moving the Internet Identity canister to a new subnet soon, which is only possible due to the described property.

I don’t, unfortunately. It’s a mess, since you have to first encode the argument as Candid, then you have to assemble the ingress message as CBOR and compute the request id. I was saying that it’s possible, not that it’s easy…

Well the canister can use the HTTP request API to make a query call to itself. And then it could use the HTTP request API to submit the request to the boundary node. So once we have HTTP queries, the canister can do this.

But yeah, all this wouldn’t be necessary if canisters could control neurons directly.

1 Like

Thank you! This is good to know. I misunderstood the video when it said the subnet would sign the certificate and had not taken a look at the spec yet.

Copy that. I may still try to build this just to learn from the experience.

I would like to draft a governance proposal requesting that DFINITY add this feature to their roadmap, or at least consider it in their horizon planning. I’m just not sure how that process works now given recent discussions on the topic. I want to respect y’alls processes.

1 Like

If you’re referring to the recent discussion on priorities: I think the proposal you have in mind is clearly a (technically straightforward) proposed change to the IC governance system. Especially if it is phrased like that (a proposal to change the governance system, not necessarily about who implements it and when), I think it is clearly suitable and expect that fact to be uncontroversial. That said, it may make sense to describe the intent in a forum thread first.