Substrate 通过助记词转换Public key、SS58 Address、AccountId的常见方式

内容分享1周前发布
1 0 0

简介

  • 某些情况下我们获取到用户提交的助记词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);

  • 获取SS58Address

// 实则这个更简单。
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);

  • 获取SS58Address

// 实则这个更简单。
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定义一个泛型方法:
  • Substrate 通过助记词转换Public key、SS58 Address、AccountId的常见方式

抽象出公用方法

  • 如下代码就是我的实现举例:

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);
}

结束

  • 感谢阅读。
© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...