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多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Spring Security 前后端分离场景下的会话并发管理

《SpringSecurity前后端分离场景下的会话并发管理》本文介绍了在前后端分离架构下实现SpringSecurity会话并发管理的问题,传统Web开发中只需简单配置sessionManage... 目录背景分析传统 web 开发中的 sessionManagement 入口ConcurrentSess

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块