安装substrate-node-template
这篇文章的内容基于substrate-node-template,安装该项目的方法在之前的文章:《创建第一条Substrate区块链》介绍过,可按文中方法自行安装。
更新Runtime
当节点运行逻辑变更后,旧版本节点生成的区块仍然存在,可以使用purge-chain子命令清除之前生成的区块,以便开发:
cd substrate-node-template./target/release/node-template purge-chain –dev
再次启动最近更改的节点:
./target/release/node-template –dev
substrate-node-template还提供了一个init.sh脚本,可以保持在进行Substrate开发时使用最新的Rust stable和nightly版本。
./scripts/init.sh
创建自定义pallet
现在开始在template模块的基础上修改代码,创建自己的模块。
1、打开substrate-node-template/pallets/template/src/lib.rs,修改代码如下:
#![cfg_attr(not(feature = \”std\”), no_std)]use frame_support::{debug, decl_module, dispatch::DispatchResult};use frame_system::{ensure_signed};use sp_runtime::print;pub trait Trait: frame_system::Trait {}decl_module! {pub struct Module<T: Trait> for enum Call where origin: T::Origin {#[weight = 10_000]pub fn say_hello(origin) -> DispatchResult {let caller = ensure_signed(origin)?;print(\”Hello World\”);debug::info!(\”Request sent by: {:?}\”, caller);Ok(())}}}
2、这里使用了sp_runtime,需要在pallets/template/Cargo.toml修改配置:
(1)、[dependencies]下添加:
sp-runtime = { default-features = false, version = \’2.0.0\’ }
sp-runtime原来在[dev-dependencies]下,移过来即可。
(2)、[features]的std下添加:
\’sp-runtime/std\’,
3、还有两个文件,pallets/template/src/mock.rs和pallets/template/src/tests.rs暂时用不上,可以删除。
4、修改runtime/src/lib.rs的代码:
(1)、修改第265行代码:
impl pallet_template::Trait for Runtime {type Event = Event;}
改为:
impl pallet_template::Trait for Runtime {}
这里是配置模块使用的类型,template模块默认是使用Event的,现在不使用,需要删除。
(2)、修改第285行代码:
TemplateModule: pallet_template::{Module, Call, Storage, Event<T>},
改为:
TemplateModule: pallet_template::{Module, Call},
同样是template模块使用的类型,这里是修改construct_runtime!宏中的配置。
编译、启动模板节点
使用cargo build命令编译源码为可执行文件:
cargo +nightly-2020-08-23 build –release
然后启动模板节点:
./target/release/node-template –dev -lruntime=debug
注意,这里增加了一个选项-lruntime=debug,这样才会在控制台打印Debug信息。
在polkadot.js Apps中提交交易
打开https://polkadot.js.org/apps,切换网络为DEVELOPMENT-Local Node:
选项卡选择开发者-交易,“提交下面的外部信息”选择templateModule,会自动获取到定义的函数sayHello():
点击右下角“提交交易”按钮,点击“签名并提交”:
可以看到,使用了125.0001 nano Unit的交易费用。
查看控制台,可以看到打印出了“Hello World”和调试信息:
错误处理
模块函数必须返回Result类型用来处理函数中的错误,返回Ok()表示成功,返回Err()表示失败。
在返回Result的函数末尾使用?运算符,可以将函数进行扩展,例如:
my_function()?
表示
match my_function() { Ok(value) => value, Err(msg) => return Err(msg),}
上面源码中的
ensure_signed(origin)?
就使用了这种错误处理机制。
创建Runtime存储
Runtime是基于Substrate的区块链的执行逻辑,也称为状态转换函数(State Transition Function,STF),以WebAssembly二进制文件格式存储在区块链上。
这篇文章介绍Substrate版本的Hello World,只使用了decl_module!宏,没有涉及到存储。
下一篇文章会创建Runtime存储,会使用到decl_storage!宏。