课程大纲

  1. 使用 SDK 搭建一个简易网站
  2. Motoko 语言简介
  3. Canister 智能合约
  4. 用 Motoko 做后端
  5. 用 Javascript 做前端

第二课-课程要求

用 motoko 实现一个快排函数:
quicksort : [var Int] -> ()
要求:

  1. 用 moc 调试运行
  2. 把函数封装在一个 canister 里面
    public func qsort(arr: [Int]): async [Int]
  3. 部署到主网
  4. 使用主网的 Candid UI 调试运行
    https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app

课程内容回顾

ICP上的智能合约

image-20220819102005820

Motoko 编程语言基本介绍

ICP 为什么需要一门新的语言?

  • 不是必须的,C, C++, Rust 都可以编译到 Wasm
  • 缺少一个高级语言同时满足:安全、高效、容易上手
  • 适配平台特性:Actor 模型、权限管理、代码升级、跨语言调用

image-20220819100856212

1.Motoko 语言的特点

  • 静态类型,语法接近 JavaScript/TypeScript
  • 面向对象,但不支持继承
  • 支持 await/async 异步通信
  • 结构化类型推断
  • 安全的数值计算
  • 没有 NULL 指针
  • 自动内存回收机制 (GC, copying/compacting/generational)

2.Motoko 基础概念

  • 程序 (program)
  • 声明 (declaration)
  • 表达式 (expression)
  • 值 (value)
  • 变量 (variable)
  • 类型 (type)

官方介绍文档:https://smartcontracts.org/docs/language-guide/motoko-introduction.html

注意点

  • 使⽤ := 作为通⽤赋值运算符
  • 代码块结束需 ;
  • 声明可变变量需 var 语法
  • 如果方法有返回值,最后一行代码块表示返回语句,可以不加分号

3.Motoko 基础库

数字类型:Int Int8 Int16 Int32 Int64 Nat Nat8 Nat16 Nat32 Nat64 Float
常用类型:Bool Char Array Text Option Result Iter Func None Hash
数据结构:Buffer List AssocList Stack Deque Heap RBTree HashMap Trie TrieMap TriSet

系统工具:Principal Blob Random CertifiedData Time Debug Prelude

https://smartcontracts.org/docs/base-libraries/stdlib-intro.html
https://github.com/dfinity/motoko-base

4.Motoko Canister

每个 Canister 都是一个 Actor,它的公共方法 (public method) 可供异步调用。

1
2
3
4
5
actor {
public func greet(name : Text) : async Text {
return "Hello, " # name # "!";
};
};

数据描述语言 Candid 用来规范 Canister 所提供的数据类型、服务接口等。

1
2
3
service : {
greet: (text) -> (text);
}

candid介绍:What is Candid?

5.moc编译器

1
2
3
4
5
6
7
8
9
# 查看编译器位置 
dfx cache show
# 添加编译器依赖到环境
#1、临时配置编译器依赖环境,但会话关闭就没有了
export PATH=$(dfx cache show):$PATH
#2、永久配置编译器依赖环境
echo "export PATH=\$(dfx cache show):\$PATH" >> ~/.bashrc
# 查看是否成功
which moc

VS Code 插件

主要是Vs Code插件的演示,

  • WSL插件
  • motoko代码编译检查插件:需要在project的根目录下打开vscode . 代码提示才有效果

Candid UI

本地:http://127.0.0.1:8000/?canisterId=r7inp-6aaaa-aaaaa-aaabq-cai

ic:https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/

Motoko Playground

地址:https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/

作业点评

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import Array "mo:base/Array";
import Int "mo:base/Int";
import Nat "mo:base/Nat";
actor {

public func qsort(arr: [Int]) : async [Int] {
// 将不可变数组转换为可变数组
var newArr:[var Int] = Array.thaw(arr);
sort(newArr, 0, newArr.size()-1);
// 将可变数组转换为不可变数组
Array.freeze(newArr)
};

func sort(arr:[var Int],low:Nat,high:Nat){
// check point 1/2
if(low>=high) return;
var temp = arr[low];
var left = low;
var right = high;
while(left < right){
while(arr[right] >= temp and right > left){
right -= 1;
};
arr[left] := arr[right]; // swap 1/3
while(arr[left] <= temp and left < right){
left += 1;
};
arr[right] := arr[left]; // swap 2/3
};
arr[right] := temp; // swap 3/3
if(left >= 1) // check point 2/2
sort(arr,low,left-1);
sort(arr,left+1,high);
};
};

官方示例:https://github.com/dfinity/examples/blob/master/motoko/quicksort/src/Quicksort.mo