# Use motoko to upgrade canister and child canister code

**URL:** <https://forum.dfinity.org/t/use-motoko-to-upgrade-canister-and-child-canister-code/34213>\
**Category:** Motoko\
**Tags:** Discussing\
**Created:** [August 16, 2024, 3:26pm UTC](https://forum.dfinity.org/t/use-motoko-to-upgrade-canister-and-child-canister-code/34213 "2024-08-16T15:26:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Reuben](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/reuben/32/16168_2.png) [@Reuben](https://forum.dfinity.org/u/Reuben)\
**Post date:** [August 16, 2024, 3:26pm UTC](https://forum.dfinity.org/t/use-motoko-to-upgrade-canister-and-child-canister-code/34213/1 "2024-08-16T15:26:11Z")

</div>

When we have many canisters, it is troublesome to upgrade them one by one.  
Or if our canister is created by the root canister and we are not the controller.  
And when we need to disperse permissions and do not want to deploy directly by someone’s local identity.  
You can consider using this method for version management through the motoko language

We need the `latest wasm file` of the module corresponding to the target canister, and when creating canister, you need to specify the module that calls the upgrade api as its controller.

First, you need to copy the ic-manage declaration to the local  
`https://github.com/johnxiaohe/ICP-Spark/blob/dev/src/spark_backend/management.mo`

Then declare the IC management module client and upgrade method in the module responsible for the upgrade

```auto
actor{
        type Management = management.Management;
        let mng : Management = actor("aaaaa-aa");
        public shared func updatecodeWithoutArgs(wasm: [Nat8], cids:[Text]): async(Bool){
                for(cid in Iter.fromArray(cids)){
                        await mng.install_code({
                                arg = to_candid();
                                wasm_module = wasm;
                                mode = #upgrade;
                                canister_id = Principal.fromText(cid);
                        });
                };
                return true;
        };
        public shared func updatecodeWithArgs(wasm: [Nat8], cids:[Text]): async(Bool){
                for(cid in Iter.fromArray(cids)){
                        await mng.install_code({
                                arg = to_candid('arg1','arg2','arg3','arg4');
                                wasm_module = wasm;
                                mode = #upgrade;
                                canister_id = Principal.fromText(cid);
                        });
                };
                return true;
        };
}

```

wasm file stream can obtain wasm file generation stream through js client, call motoko canister to upgrade our main canister, child canister

When our child Canister has many dynamic init parameters. When updating the code, the same init parameters are needed as arg. You can use the following method to pass the parameters in order to generate blob.

```auto
to_candid('arg1','arg2','arg3','arg4')

```

Because the init parameters of child are dynamic and unpredictable. It is recommended that the child canister provide an argsblob interface, and obtain the init args blob information of the canister through the interface during the upgrade

Thanks to these authors for their ideas

> [@Encode Principal to Candid arguments](https://forum.dfinity.org/t/encode-principal-to-candid-arguments/10465):
>
> I have got a manager canister that creates user canisters. These user are actor that takes a principal as argument. actor class UserBucket(owner: Principal) = this { ... So far, so good. Now, through the manager I am trying to implement a function that can update the code of these user canisters. public func installCode(canisterId: Principal, owner: Principal, wasmModule: Blob): async() { await IC.install\_code({ arg = Blob.toArray(Principal.toBlob(owner)); …

> <https://github.com/peterpeterparker/motoko_to_rust_migration/blob/1d51608bbea4f7257d6ed0916a5238d4427ec13b/src/motoko_to_rust_migration_backend/main.mo>

> [@Need help implementing install\_code() canister method](https://forum.dfinity.org/t/need-help-implementing-install-code-canister-method/18313):
>
> I’m trying to implement the installCode\_ method below. The canister actor that I’m trying to install the wasmModule to is constructed like so: shared(msg) actor class Journal (principal : Principal) = this { //code } I’m pretty sure the issue with the implementation is with the way I’m defining the arg variable. private func installCode\_ (arg: Blob, wasmModule: Blob, canister\_id: Principal) : async () { await ic.stop\_canister({canister\_id = canister\_id}); await ic.install\_…

---

<div class="post-metadata">

**Author:** ![Reuben](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/reuben/32/16168_2.png) [@Reuben](https://forum.dfinity.org/u/Reuben)\
**Post date:** [August 16, 2024, 3:28pm UTC](https://forum.dfinity.org/t/use-motoko-to-upgrade-canister-and-child-canister-code/34213/2 "2024-08-16T15:28:15Z")

</div>

I created a versioning platform for my project because there were too many derived containers to manage. I will continue to develop this platform if you need it.

 ![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/a/8/a8049a08d77dead144c10a4445c19d39158ea159.png)

---

<div class="post-metadata">

**Author:** ![Reuben](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/reuben/32/16168_2.png) [@Reuben](https://forum.dfinity.org/u/Reuben)\
**Post date:** [August 16, 2024, 4:04pm UTC](https://forum.dfinity.org/t/use-motoko-to-upgrade-canister-and-child-canister-code/34213/3 "2024-08-16T16:04:16Z")

</div>

But I think args is meaningless in update code, because it is only useful during initialization. Update code should not check args
