substrate进阶(1)-概念和理论

Pallet相关的基础概念以及理论汇总,方便查阅

1. 概念

  1. 优点:
    1. substrate模块化(积木),封装了区块链各层技术,可以直接使用,也可以定制化开发
    2. 可以一条链为一个应用开发,降低多个应用抢占一条链资源导致链被阻塞的现象(ethereum),也就是平行链概念
  2. 应用方式
    1. 直接编译生成默认的链即可使用:可以参考:substrate基础(1)-substrate-node-template编译及部署
    2. 使用bstrate frame构建运行时:也就是根据自己的业务需要,选择不同的pallet或者自行开发一些pallet,然后组成一个完整的链
    3. 使用substrate core:抛开frame,自行开发,难度很大,一般也不建议

2. Rust前置基础

substrate中,由于本身框架特性,Rust的使用是及其灵活的,如果没有良好的Rust基础,想深入了解Rust会很累的。
比如宏、trait等,一定要掌握,substrate的灵魂

2.1 trait基础

  1. 孤儿规则:
    如果想要为类型A实现trait T,那么A或者T至少有一个是在当前作用域中定义的:
    以下正确和错误的例子,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//正确的例子,遵守规则
pub trait MyTrait {
fn print();
}

pub struct MyType;

impl MyTrait for MyType {
fn print() {
println!("This is ok.");
}
}

//错误的例子,无法编译通过
use std::fmt::{Error, Formatter};
impl std::fmt::Debug for () {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
Ok(())
}
}

之所以错误的例子无法编译,是因为:不管是trait Debug的定义还是类型()的定义都是外部引入的,所以无法在代码中为类型()实现trait Debug。

  1. trait对象
    常规标准使用
    Rust中不直接将trait当作数据类型使用,但可以将实现了某个trait的具体的类型当作trait对象使用(可以理解为接口,不直接作为数据类型的):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
trait Drive{
fn drive(&self);
}
struct Truck;
impl Drive for Truck {
fn drive(&self) {
println!("Truck run!");
}
}
struct MotorCycle;
impl Drive for MotorCycle {
fn drive(&self) {
println!("MotorCycle run!");
}
}
fn use_transportation(t: Box<dyn Drive>) {
t.drive();
}
fn main() {
let truck = Truck;
use_transportation(Box::new(truck));
let moto = MotorCycle;
use_transportation(Box::new(moto));
}

本例中use_transportation的参数就是一个trait对象,不关注具体的类型,只需要它具备drive能力即可。

  1. trait的继承
    只支持Trait之间的继承,比如Trait A继承Trait B,语法为:
1
2
trait B{}
trait A: B{}

Trait A继承Trait B后,当某个类型C想要实现Trait A时,还必须要同时也去实现trait B

  1. 关联类型
    关联类型是在trait定义的语句块中,申明一个自定义类型(使用type),这样就可以在trait的方法签名中使用该类型:
    注:type的类型可以指定要实现哪些trait,比如:type Event: ToString;表示Event类型要实现能够转化为String类型的trait。对此,当赋实际类型时,举例:type Event = u64;
1
2
3
4
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}

当为某个类型实现具有关联类型的trait时,需要指定关联类型为具体的类型:

1
2
3
4
5
6
7
8
9
10
11
struct Counter(u32);
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
// --snip--
}
}
fn main() {
let c = Counter(1);
c.next();
}

2.2 宏

总结

本文编辑中,会根据需要不断累加

  • Copyrights © 2017-2023 Jason
  • Visitors: | Views:

谢谢打赏~

微信