简介
- 某些情况下我们获取到用户提交的助记词
mnemonic
后,需要转换成公钥信息进行保存等操作,本文来简单介绍转换的方式。
- 注意这里的代码是不支持 no-std的。
引入的类库
- 这里面我直接复制我测试代码中的引用,有些是多余的,暂时不做筛选。
use frame_support::sp_runtime::{MultiSignature, CryptoTypeId};
use frame_support::sp_runtime::app_crypto::{Public, Pair, sr25519, ed25519, Ss58Codec, CryptoTypePublicPair};
use frame_support::sp_runtime::traits::{Verify, IdentifyAccount};
use frame_support::pallet_prelude::Encode;
use sp_core::hexdisplay::HexDisplay;
use sp_runtime::AccountId32;
获取 ed25519 也就是GRANDPA的公钥信息
// 首先拿到 account_id 的Vec<u8>数组
let account_id = ed25519::Pair::from_string("助记词...", None)
.expect("Seed error of ed25519.").public().to_vec();
// 实际上公钥就是通过这个数组的数据转成16进制而成的。
let account_id = sp_core::hexdisplay::HexDisplay::from(&account_id);
println!("用户公钥 = {:?}", &account_id);
// 其实这个更简单。
account_id = ed25519::Pair::from_string("助记词...", None)
.expect("Seed error of ed25519.").public().to_ss58check()
println!("用户SS58格式地址 = {:?}", &account_id);
获取 sr25519 也就是Babe,以及Aura,和我们常用的公钥信息
// 首先拿到 account_id 的Vec<u8>数组
let account_id = sr25519::Pair::from_string("助记词...", None)
.expect("Seed error of sr25519.").public().to_vec();
// 实际上公钥就是通过这个数组的数据转成16进制而成的。
let account_id = sp_core::hexdisplay::HexDisplay::from(&account_id);
println!("用户公钥 = {:?}", &account_id);
// 其实这个更简单。
account_id = sr25519::Pair::from_string("助记词...", None)
.expect("Seed error of ed25519.").public().to_ss58check()
println!("用户SS58格式地址 = {:?}", &account_id);
改进
- 通过观察可以看到 sr25519、ed25519代码的处理方式几乎一样,那样的话我们就可以找一些共同点,从而抽象出一个公用函数。
- sr25519和ed25519都定义一个结构体Public,比如上面的 Pair::from_string 接口这个Public结构体就都做了实现,尤其Public 中的 CryptoType 是他们必须实现的借口,所以直接可以通过这个trait定义一个泛型方法:
抽象出公用方法
fn extract_hex_of_public<TPublic: Public>(raw_data: &str) // -> HexDisplay
where
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
let account_id = TPublic::Pair::from_string(raw_data, None).expect("Seed error").public();
let account_id: AccountId32 = AccountPublic::from(account_id).into_account();
let account_u8: [u8; 32] = account_id.into();
let account_id = sp_core::hexdisplay::HexDisplay::from(&account_u8);
println!(" extract_hex_of_public = {:?}", account_id);
}
结束