Motoko : encode an object into Candid to pass arguments into install_code

Hello,
I am trying to use the IC management canister to install some wasm into an already created canister trough this method :

public type ICActor = actor {
install_code: shared(params: InstallCodeParams) -> async ();
};

 public type InstallCodeParams = {
        mode: InstallMode;
        canister_id: Principal;
        wasm_module: Blob;
        arg: Blob;
 };

I need to pass 4 arguments; as far as I understand they need to be passed as a Blob encoding their candid representation.
Is there an easy way to get the candid blob directly from the object in Motoko, something like didc encode but that could be used at runtime in Motoko ? (I would rather avoid to manually write the Blob…)

@skilesare is it what the bounty behind Bounty - ICDevs.org CBOR and Candid Motoko Parser is about ?
I would like to be able to do something like Candid.encodeBlob(object) in Motoko.

3 Likes

Only the arg field is Candid encoded. If the wasm module doesn’t take init args, you can pass an empty blob as well.

We are adding a new primitive in Motoko to allow serializing Motoko values into blob. It’s still work in progress.

2 Likes

!!! Will they be candid encoded? If so we can simplify the bounty quite a bit. We still need CBOR.

1 Like

Yes, the plan is to have primitives for to_candid and from_candid that converts between Motoko tuples and Blob.

2 Likes

Yes I was talking about the arg field because the module needs arguments to be initialized; that will be really amazing to have that feature!

@chenyan

When you say “converts between Motoko tuples and Blob”, would this not then apply to the record type?

The ability to Blob encode an record/object is especially important because initializing an actor canister class with a record better supports backwards compatibility when upgrading, as opposed to than a list of arguments.

Not having this feature in Motoko is borderline blocking, as it limit Motoko devs in the following ways:

  • If we want to use values that already exist on the canister memory that would be rolling out the dynamic upgrades it makes sense that this would happen on the backend. Not being able to Blob encode a record forces Motoko developers who want to perform upgrades on the backend to simplify their instatiation arguments for an actor canister

Or

  • It forces us to use @dfinity/candid to encode the arguments from the frontend using Javascript or tooling like didc for pushing out upgrades where the canister requires multiple instantiation arguments. This becomes awkward when an upgrade involves pulling down data to the client from one canister in order to retrieve the arguments necessary to rollout upgrades with the proper arguments to other canisters. It also means additional repeated development time where all Motoko development teams are building out custom tooling farther away from the canister rolling out the upgrades, and all of this could be solved with improved Motoko encoding capability.

@claudio @matthewhammer

I was looking at candid/tools/didc at master · dfinity/candid · GitHub, and would love a Motoko equivalent of

didc encode ...

There might need to be a type definition in there <T>, but how hard would it be to add something with this functionality to the Blob class in motoko-base?

The debug_show is amazing at converting types to Text, how difficult would it be to convert a well typed record to a Blob from the Motoko side?

Is there a prim functionality that I could leverage?

1 Like

The top-level Candid message is always a tuple: in the textual representation, Candid values are always wrapped inside a parenthesis. A record type in init arg is actually a one-tuple with record type: ( record {...} ).

1 Like

Oh that’s amazing then! Thanks Chenyan, really looking forward to this