示例:
直接进入正题,现在,我举个使用Ledger Actor动态创建canister的例子。
假如我们想在A.mo的actor中动态创建B.mo中的actor类,则:
一、先创建Types.mo模块,在其中写入以下代码:
module IC{ public type canister_settings = { freezing_threshold : ?Nat; controllers : ?[Principal]; memory_allocation : ?Nat; compute_allocation : ?Nat; }; public type definite_canister_settings = { freezing_threshold : Nat; controllers : [Principal]; memory_allocation : Nat; compute_allocation : Nat; }; public type user_id = Principal; public type wasm_module = [Nat8]; public type canister_id = Principal; public type ICActor = actor { canister_status : shared { canister_id : canister_id } -> async { status : { #stopped; #stopping; #running }; memory_size : Nat; cycles : Nat; settings : definite_canister_settings; module_hash : ?[Nat8]; }; create_canister : shared { settings : ?canister_settings } -> async { canister_id : canister_id; }; delete_canister : shared { canister_id : canister_id } -> async (); deposit_cycles : shared { canister_id : canister_id } -> async (); install_code : shared { arg : [Nat8]; wasm_module : wasm_module; mode : { #reinstall; #upgrade; #install }; canister_id : canister_id; } -> async (); provisional_create_canister_with_cycles : shared { settings : ?canister_settings; amount : ?Nat; } -> async { canister_id : canister_id }; provisional_top_up_canister : shared { canister_id : canister_id; amount : Nat; } -> async (); raw_rand : shared () -> async [Nat8]; start_canister : shared { canister_id : canister_id } -> async (); stop_canister : shared { canister_id : canister_id } -> async (); uninstall_code : shared { canister_id : canister_id } -> async (); update_settings : shared { canister_id : Principal; settings : canister_settings; } -> async (); }; }
然后在A.mo中引入Types:
import Types "./Types";
二、在A.mo和B.mo中都引入以下base库文件:
import Cycles "mo:base/ExperimentalCycles"; //目前为实验版,后续会更新
并添加以下代码:
public query({caller}) func cycleBalance() : async Nat{ Cycles.balance() }; public shared({caller}) func wallet_receive() : async Nat { Cycles.accept(Cycles.available()) };
三、对ledger actor进行调用,以创建B canister:
假设B.mo大致为以下样式:
//import ... shared({caller}) actor class B(installer : Principal) = this{ //... };
在A.mo中添加以下代码:(仅摘取部分代码)
import RBT "mo:base/RBTree"; //RB树的库文件 import Nat "mo:base/Nat"; import Principal "mo:base/Principal"; import B "./B.mo"; private stable var b_index : Nat = 0; private let Bs = RBT.RBTree<Nat, Principal>(Nat.compare); //存储创建的B canister private let IC : Types.IC.ICActor = actor "aaaaa-aa"; //ledger actor的ID private let CYCLE_LIMIT = 1_000_000_000_000; //根据需要进行分配 //动态创建canister的函数 public shared({caller}) func createB() : async Result.Result<Principal, Text>{ Cycles.add(CYCLE_LIMIT); let b = await B.B(caller); let principal = Principal.fromActor(b); await IC.update_settings({ canister_id = principal; settings = { freezing_threshold = ?2592000; controllers = ?[caller]; //A不作为B的控制者的写法 memory_allocation = ?0; compute_allocation = ?0; } }); Bs.put(b_index, principal); b_index += 1; #ok(principal) };
完毕。
Comments 3 条评论
IC.update_settings是必须的吗?
@匿名 建议写上,不写的话应该也能创建(now
hello!,I love your writing very so much! share we be in contact more approximately your post on AOL? I require a specialist in this area to solve my problem. Maybe that’s you! Having a look ahead to see you.