dfinity开发——动态创建Canister与Canister的控制器管理

2023-10-14 13:40

本文主要是介绍dfinity开发——动态创建Canister与Canister的控制器管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

这是dfinity中动态创建Canister例子,就是在A.mo 的actor中动态创建B.mo中的actor类。

项目

1.首先创建一个项目

dfx new CanisterMGT

2.启动项目

cd CanisterMGT
dfx start --clean

3.在项目下创建types.mo 和 sub.mo文件
在这里插入图片描述

4.types.mo是canister所需要的类型和属性,添加如下代码:

module{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 : { controllers : [Principal] };//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 ();};
}

5.sub.mo是接下要在main.mo里面创建的canistet,sub.mo里面的代码就是它自身要实现的代码,但cycleBalance() 和wallet_receive()这两个属性是必须要添加在里面的,有必要也添加下canister的升级代码。

import Cycles "mo:base/ExperimentalCycles"; 
import Nat "mo:base/Nat";shared({caller}) actor class Sub(installer : Principal) = this
{public query({caller}) func cycleBalance() : async Nat{Cycles.balance()};public shared({caller}) func wallet_receive() : async Nat {Cycles.accept(Cycles.available())};public shared query ({caller}) func whoami() : async Principal {caller};stable var counter = 0;public query func get() : async Nat{return counter;};public func inc() : async () {counter += 1;};
}

6.main.mo是创建canister的代码

import Types "./types";
import Cycles "mo:base/ExperimentalCycles"; 
import RBT "mo:base/RBTree";
import Nat "mo:base/Nat";
import Principal "mo:base/Principal";
import Sub "./sub";
import Array "mo:base/Array";actor Self
{public type canister_info = {canister_id : Principal;id:Nat;};//获取当前pidpublic shared query ({caller}) func whoami() : async Principal {caller};//获取当前canister idpublic shared query ({caller}) func getCanisterId() : async Principal{Principal.fromActor(Self);};//记录创建的canister个数private stable var subs_index : Nat = 0;private let subs = RBT.RBTree<Nat, Principal>(Nat.compare); //存储创建的sub canisterprivate let IC : Types.ICActor = actor "aaaaa-aa"; private let CYCLE_LIMIT = 50; //创建canister要分配的cycle//动态创建canister的函数,返回创建的canisister idpublic shared({caller}) func createSub() : async canister_info{Cycles.add(CYCLE_LIMIT);let sub = await Sub.Sub(caller);let principal = Principal.fromActor(sub);await IC.update_settings({canister_id = principal;settings = {freezing_threshold = ?20;controllers = ?[principal]; //控制器是它自身memory_allocation = ?0;compute_allocation = ?0;}});subs.put(b_index, principal);subs_index += 1;let canister_info = {canister_id = principal;id = subs_index;}};//获取canister的控制器public func get_controllers(canister_id : Principal) : async [Principal] {let status = await IC.canister_status({ canister_id = canister_id });return status.settings.controllers;};
};

7.运行项目

dfx deploy

8.调用创建canister的接口

dfx canister call CanisterMGT createSub

动态创建第一个canister

(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call CanisterMGT createSub
(record { id = 1 : nat; canister_id = principal "r7inp-6aaaa-aaaaa-aaabq-cai" })

9.现在来访问新创建的这个canister里面的属性
查看cycles,这50个是刚刚转进去的

(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call r7inp-6aaaa-aaaaa-aaabq-cai cycleBalance
(50 : nat)

计数

base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call r7inp-6aaaa-aaaaa-aaabq-cai get         
(0 : nat)
(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call r7inp-6aaaa-aaaaa-aaabq-cai inc
()
(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call r7inp-6aaaa-aaaaa-aaabq-cai get
(1 : nat)
(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call r7inp-6aaaa-aaaaa-aaabq-cai inc
()
(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call r7inp-6aaaa-aaaaa-aaabq-cai get
(2 : nat)

然后再创建一个canister

(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call CanisterMGT createSub                   
(record { id = 2 : nat; canister_id = principal "rkp4c-7iaaa-aaaaa-aaaca-cai" })

访问里面的属性

(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call rkp4c-7iaaa-aaaaa-aaaca-cai get
(0 : nat)
(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call rkp4c-7iaaa-aaaaa-aaaca-cai inc
()
(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call rkp4c-7iaaa-aaaaa-aaaca-cai get
(1 : nat)
(base) dalao@dalaodeMacBook-Pro CanisterMGT % 

10.查看控制状态

如果canister当前只有一个控制器,它是拒绝外部访问它的控制器

(base) dalao@dalaodeMacBook-Pro CanisterMGT % dfx canister call CanisterMGT get_controllers '(principal "r7inp-6aaaa-aaaaa-aaabq-cai")'
Error: The Replica returned an error: code 4, message: "Only the controllers of the canister r7inp-6aaaa-aaaaa-aaabq-cai can control it.
Canister's controllers: r7inp-6aaaa-aaaaa-aaabq-cai
Sender's ID: rrkah-fqaaa-aaaaa-aaaaq-cai"

11.创建canister分配过去的cycle记得回收,我在测试的时创建一堆canister之后,退出环境之后才记得没有回收cycle,现在还在找办法找回来。

这篇关于dfinity开发——动态创建Canister与Canister的控制器管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/210873

相关文章

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java