前言
整理在開發pallet過程中使用到的代碼列印控制台。
主要有以下幾種:
- Logging utilities
- Printable trait
- If std
建立項目
進入到/substrate-node-template中,接着進入到目錄pallets中,建立我們自己的lfhuang-debug-pallet。并且将這pallet加載到runtime中。
使用Logging utilities
通過使用 log crate 代碼包在代碼中使用log輸出日志,包括debug和info等,和Java類似用法。
需要引入的依賴:
[package]
name = "lfhuang-debug-pallet"
description = "FRAME pallet template for debug"
authors = ["lfhuang"]
...
[dependencies]
log = "0.4.17"
...
接着可以在lib.rs業務代碼使用log進行列印。
#[pallet::weight(0)]
pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult {
let who = ensure_signed(origin)?;
<Something<T>>::put(something);
// Debug方式一 log
log::info!(
" ######################## called by something:{:?} and signer:{:?}",
something,
who
);
Self::deposit_event(Event::SomethingStored(something, who));
Ok(())
}
通過調用交易憑證能看到輸出日志資訊如下:
使用Printable trait
通過使用Printable trait 代碼包實作它,下面通過Error類型實作列印輸出日志資訊。需要開啟debug環境變量模式啟動。
目前非test調試代碼,是以sp-runtime的相關依賴需要放到[dependencies]依賴下。
...
[dependencies]
sp-runtime = { version = "7.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" }
...
// 引入依賴
use sp_runtime::print;
use sp_runtime::traits::Printable;
...
#[pallet::error]
pub enum Error<T> {
/// Value was None
NoneValue,
/// Value reached maximum and cannot be incremented further
StorageOverflow,
}
impl<T: Config> Printable for Error<T> {
fn print(&self) {
match self {
Error::NoneValue => "Invalid Value".print(),
Error::StorageOverflow => "Value Exceeded and Overflowed".print(),
_ => "Invalid Error Case".print(),
}
}
}
...
#[pallet::weight(0)]
pub fn cause_error(origin: OriginFor<T>) -> DispatchResult {
// 檢查是否已簽名
let _who = ensure_signed(origin)?;
print(" ########### 錯誤原因... #############");
match <Something<T>>::get() {
None => {
print(Error::<T>::NoneValue); // Debug方式二,預設是debug級别,是以啟動時候把環境變量調整到debug啟動
Err(Error::<T>::NoneValue)?
},
Some(old) => {
let new = old.checked_add(1).ok_or({
print(Error::<T>::StorageOverflow);
Error::<T>::StorageOverflow
})?;
<Something<T>>::put(new);
Ok(())
},
}
}
首次調用cause_error沒有值則會報Error::NoneValue錯誤,需要調用do_something方法設定一個值,接着再掉用cause_error方法則存儲值會加1,同時也會報Error::StorageOverflow錯誤。
使用print
使用print函數進行調試記錄runtime執行狀态。需要導入use sp_runtime::print;和上面的Printable trait方式差不多,輸出列印日志都使用到了print();需要開啟debug環境變量模式啟動。
官網例子中的print!();編譯報錯。部分代碼例子如下:
#[pallet::weight(0)]
pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult {
let who = ensure_signed(origin)?; // 檢查是否已簽名
print(" 開始設定值..."); // Debug方式三 print,預設是debug級别,是以啟動時候把環境變量調整到debug啟動
<Something<T>>::put(something);
print(" 存儲值完成...");
// Debug方式一 log
log::info!(
" ######################## called by something:{:?} and signer:{:?}",
something,
who
);
Self::deposit_event(Event::SomethingStored(something, who));
Ok(())
}
使用if_std
使用if_std宏的方式實作調試。
...
[dependencies]
sp-std = { version = "5.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.37" }
...
// 引入依賴
use sp_std::if_std;
println!語句應該在if_std宏的内部。
#[pallet::weight(0)]
pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult {
let who = ensure_signed(origin)?; // 檢查是否已簽名
print(" 開始設定值..."); // Debug方式三 print,預設是debug級别,是以啟動時候把環境變量調整到debug啟動
<Something<T>>::put(something);
print(" 存儲值完成...");
// Debug方式一 log
log::info!(
" ######################## called by something:{:?} and signer:{:?}",
something,
who
);
// Debug方式四 if_std!宏
if_std! {
println!(" ################## Hello native world! something value: {}",something);
println!(" ################## 調用者的交易賬戶是: {:#?}", who);
}
Self::deposit_event(Event::SomethingStored(something, who));
Ok(())
}
檢查編譯代碼
cargo check -p node-template-runtime --release
編譯節點模闆
傳回到項目根目錄下/substrate-node-template
cargo build --package node-template --release
啟動節點
運作一個臨時節點,該節點将在流程結束時删除所有配置,指定開發鍊
./target/release/node-template --tmp --dev
使用RUST_LOG環境變量運作節點二進制檔案以列印值。
RUST_LOG=runtime=debug ./target/release/node-template --tmp --dev
連接配接節點
1、在浏覽器中輸入https://polkadot.js.org/apps/#/explorer
2、點選左上角會展開
3、在展開的菜單中點選 DEVELOPMENT
4、點選 Local Node
5、點選 switch (轉換到本地網絡)