Canister dynamically creation failed

Hi, I followed actor class creation tutorial using Motoko. It works fine
in local environment but when I’m deploying it to the IC network and try to create new bucket I get following error The Replica returned an error: code 4, message: "Creating a canister requires a fee of 100000000000 that is deducted from the canister's initial balance but only 0 cycles were received with the create_canister request." Untitled :: Internet Computer

Can someone help me to resolve this?

Guess you are using Motoko playground. We don’t allow cycle transfer in the playground, and creating canister requires cycle transfer. It’s best to use dfx and deploy to the IC for this example.

Thanks for the quick response @chenyan . I didn’t use the playground. I deployed it through my laptop with command
dfx deploy --network ic --wallet <wallet-id> --with-cycles 4000000000000

Before the line where you instantiate a new canister, you have to call the Cycles.send() method to send the cycles to the canister that you’re creating

hey @Jesse. In the documentation, they didn’t mention something like that. Why do we need to handle cycle manipulation in our code? it should inherit by default right?

Not sure why it’s not included in the documentation. I think they still have some updates to make. But it’s not handled inherently. You’ll have to explicitly send the cycles. It’s not too hard. I’ll post an example for you here when i get near my laptop. If i haven’t posted it here within 24 hrs, feel free to send me a reminder.

3 Likes

Sure @Jesse . Thanks for the help

in the canister that you’re sending the cycles from, you’ll have to do the following:

import Cycles "mo:base/ExperimentalCycles";


Cycles.add(100_000_000_000);
let canisterInstance = await CanisterFileName.ActorClassName(argument);
let amountAccepted = await canisterInstance.wallet_receive();

in the canister that you’re instantiating (the canister that will be receiving the cycles) you’ll have to define the wallet_receive() method like so:

import Cycles "mo:base/ExperimentalCycles";

private var capacity = 1000000000000000000;
private var balance = Cycles.balance();


// Returns the cycles received up to the capacity allowed
public func wallet_receive() : async { accepted: Nat64 } {
    let amount = Cycles.available();
    let limit : Nat = capacity - balance;
    let accepted = 
        if (amount <= limit) amount
        else limit;
    let deposit = Cycles.accept(accepted);
    assert (deposit == accepted);
    balance += accepted;
    { accepted = Nat64.fromNat(accepted) };
};

heres some more code you might need to include later if you want to query the balance of the canisters:


public shared(msg) func wallet_balance() : async Nat {
    return balance
};
1 Like