查看原文
其他

Subdev 讨论 ▏探究语言规则背后的含义

一块链习 一块Plus社区 2020-11-11

Parity 科技公司研发的 Substrate 框架,让我们拥有了可以几乎不受限制的快速的开发出一个完整、高性能、安全的区块链项目。
 
今年6月份,一块链习与 Polkadot 社区大使陈锡亮老师倾力打造了《Substrate快速入门与实战开发》课程。


目前第三期已经开课三周,同学们平常会在班级群将学习中遇到的难题或不解向老师、助教提问、讨论,现在将第二周班级群日常优质的讨论内容分享给大家。

Q&A  具体内容如下:

 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 

QKuoye@博士:

               

请问大家知不知道这是什么问题?是不是至少要跑一次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 都可以,按需定义。

 


更多阅读:

▎Subdev 周记 ▏区块链编程语言必不可少的三大特性

▎Substrate Off-Chian Workers 是什么?如何用?

▎Subdev分享 ▏Substrate Staking代币经济系统讲解


扫码关注公众号,回复“1”加入开发者社群


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存