Subdev 讨论 ▏探究语言规则背后的含义
01
Q: 李示佳@程序员:不同的链,地址是不是不一样?
A: 陈锡亮@讲师:不同的链,同样的public key,生成的ss58地址可以是不一样的,比如Substrate默认prefix是42,波卡是0,kusama是2。
地址主要有两种,一种是长地址格式,一种是短地址格式,长地址的就包含完整的public key,短地址就是一个index,在链上查询对应的public key。
因为这个index是有个能被收回和重新给其他人的,所以需要额外的checksum。
Q: 晓聪@程序员:为什么同样的pub key 在不同的链就不一样?
A: 陈锡亮@讲师:避免不同的链的地址混用。比如我给你打5个DOT,你给我你的kusama的地址,钱包就可以告诉我你给我的地址不对。
02
Q: Allen@程序员:请问一下index是怎么分配的呢?就是个计数器吗?还是说也要根据public key来计算的。
A: 陈锡亮@讲师:就是计数器。
Q: Allen@程序员:index使用场景是啥?钱包可以通过index转账?
A: 陈锡亮@讲师:index就是短地址。代码里面
let dest = T::Lookup::lookup(dest)?; 就是通过index得到账号。
Q: Allen@程序员:有没有可能一个index分给了A地址,然后A被回收了~这个index又被分给了B地址,还是说一起回收这个index就报废了?
A: 陈锡亮@讲师:可以分配给B,所以短地址有额外的checksum严重避免这种情况。
https://github.com/paritytech/substrate/wiki/Reclaiming-an-index
03
Q: 刘吉洋@助教:index能被收回是啥意思?
A: 陈锡亮@讲师:Substrate起始有一个开户和销户的概念的。
Q: 李示佳@程序员:这个回收是系统做的?
A: 陈锡亮@讲师:indices模块。
Q: 陈威@程序员:
f7hs是index?
A: 陈锡亮@讲师:对,应该说是短地址格式,解码后可以得到index。
Q: 陈威@程序员:刚才做了试验, 打了钱就有index了, 原本这个账户的index位置是空的
A: 陈锡亮@讲师:嗯。开户有额外的手续费的,销户可以退回部分,可以配置的。
04
Q: 陈威@程序员:这里
<randomness_collective_flip::Module<T> as Randomness<T::Hash>>::random_seed(),
删除 as Randomness<T::Hash>编译也通过, 难道跟rust版本有关系?
按道理说有这个实现, Rust应该能自己处理, 不用手动 as 处理。
impl<T: Trait> Randomness<<T as Trait>::Hash> for pallet_randomness_collective_flip::Module
<T>
我用的最新稳定版Rust,as Randomness<T::Hash> 的作用应该就是相当于编译期的检查,对类型做个断言, 可以选择删除 。
A: 陈锡亮@讲师:as xxx 在有些情况下是需要的,比如这个类型自己实现了一个同样名字的方法。但这边确实是不需要的。
Q: 陈威@程序员:了解了, 多谢老师。同名字的情况下用, 可以使用父Trait的实现。不用子Trait的实现。
pub fn create(origin) {
info!("xxxxxxxxxxxx");
我看日志打了两次。
WASM_BUILD_TYPE=release cargo run -- --dev -d target/substrate --execution=Native
跑的是单节点。
难道自己产生块的时候执行一次, 然后又自己验证一次的时候再执行一次?
是不是加入交易池的时候先执行一次, 做个检查. 然后最终出块的时候再执行一次。
A:陈锡亮@讲师:应该是出块的时候执行一次,自己重新引入的时候会再验证一次就又执行一次。
05
Q: FLYQ@程序员:有人讲一下 Cargo 依赖的规则吗?
https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#choosing-features
这里没找到在同一个仓库路径里设置不同的依赖的规则。
我有一些疑惑:
1、Cargo.toml 里面是 substrate-cli,代码里面是 substrate_cli,好像默认要把 - 改成 _ 。
2、Cargo.toml 的 git 路径里面没有指定到具体的目录,Cargo 怎么仅仅根据 [dependencies.substrate-cli]就知道这个依赖在 substrate/core/cli 下面。
A: 陈威@程序员:根toml有
[workspace]
members = [
"bin/node-template",
"bin/node-template/runtime",
"bin/node/cli", .....
可以找到的,-会改为_
Q: FLYQ@程序员:嗯嗯,还有个问题是里面有两个路径的 cli 时怎么区分的?
A: 陈锡亮@讲师:每个crate的cargo.toml里面有名字,根据这个名字匹配的。
06
Q: 陈威@程序员:
以前这个地方是最后才发事件的, 现在先发事件了, 有什么讲究吗?
A: 陈锡亮@讲师:没有,没区别。
07
Q: 村上香菜子@电商:课程上讲到一个叫makefile的东西,这个能介绍一下吗?是用rust写的,把命令行都写在一起的文件吗?
A: 陈锡亮@讲师:这个是常用的unix命令行工具,C / C++ 项目常用。我只是把make当作task runner来用。
https://zhuanlan.zhihu.com/p/47390641
08
Q: 少婷@运营:
「代表本身这个crate」
- - - - - - - - - - - - - - -
可用可不用?怎么别的都不用?
A:村上香菜子@电商:我刚刚看文档正好看到,那种写法是把自己写的crate里边放得比较深的API排列出来,方便使用的人查找和使用的做法。
https://kaisery.github.io/trpl-zh-cn/ch14-02-publishing-to-crates-io.html
不过这一节内容中文版我看半天没看懂,翻译得不太流畅。看了下英文版,讲就明白了。
https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html
09
Q: Kuoye@博士:
请问大家知不知道这是什么问题?是不是至少要跑一次make build-wasm?
A: 陈锡亮@讲师:是的。
10
Q: 于超@自由职业:error: expected `:`
--> runtime/src/kitties.rs:13:21
|
13 | pub Kitties get(fn kitties): map u32 => Kitty;
decl_storage! {
trait Store for Module<T: Trait> as Kitties {
/// Stores all the kitties, key is the kitty id / index
pub Kitties get(fn kitties): map u32 => Kitty;
/// Stores the total number of kitties. i.e. the next kitty index
pub KittiesCount get(fn kitties_count): u32;
}
}
A:于超@自由职业:把fn 去掉了,可以了。
11
Q:于超@自由职业:
1. pub Kitties get(fn kitties): map T::KittyIndex => Option<Kitty>;
第三课说,上面的写法可以改成
pub Kitties map T::KittyIndex => Option<Kitty>;
这个写法其实更好理解一些,那么加一个get(fn *) ,怎么理解这个 get(fn*) 好呢?
2.pub KittiesCount get(fn kitties_count): T::KittyIndex;
我看后面有直接调用 let kitty_id = Self::kitties_count();
从这里看有没有 get(fn*) 还是有区别的?我这么理解对吗?
A: 陈锡亮@讲师:没有 get() 的话就不能 Self::kitties_count 了,就是帮你生成一个 getter。
Q: 周洋@助教:1和2是同样的问题。正如陈老师上面说的。
加上 get(), 可以这样获取value:let kitty = Self::kitties(kitty_id);
不加只能这样获取value: let kitty = <Kitties<T>>::get(kitty_id);
12
Q:于超@自由职业:/// Stores all the kitties, key is the kitty id / index
pub Kitties get(fn kitties): map T::KittyIndex => Option<Kitty>;
这个map变量的key值,必须用泛型吗? T::KittyIndex
这个泛型感觉没起到泛型的作用啊?后面代码写起来,还麻烦好多。
<Kitties<T>>::insert(kitty_id, kitty);
要不就直接写 Kitties::insert(kitty_id, kitty);
没有起到泛型的作用。我是不是哪里理解漏了?
A:周洋@助教:这里的 T 就是你的 模块 Trait
pub trait Trait {
}
KittyIndex 定义在 Trait 里面,就必须这样使用 T::KittyIndex
KittyIndex 定义在 Trait 里面是为了使模块更通用化。其他模块可以将 KittyIndex 定义成各种类型 u64, u32 都可以,按需定义。
更多阅读:
▎Substrate Off-Chian Workers 是什么?如何用?
▎Subdev分享 ▏Substrate Staking代币经济系统讲解
扫码关注公众号,回复“1”加入开发者社群