示例:
直接进入正题,现在,我举个使用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是必须的吗?
博客作者 QiuYeDx
@匿名 建议写上,不写的话应该也能创建(now
博客作者 zoritoler imol
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.