2

Is there any way to convert an &str into an AccountId inside a substrate pallet?

I need this because a evm precompile is interactive with the pallet, and its sending the address (its already in substrate format b58) as a &str.

2 Answers 2

3

https://github.com/hack-ink/array-bytes

let account_id_32 = array_bytes::hex_n_into::<_, AccountId32, 32>(public_key_str)?;
let account_id_20 = array_bytes::hex_n_into::<_, AccountId20, 20>(public_key_str)?;

// Or you might want to use `[u8; 32]`, `[u8; 20]`.
let account_id_32 = array_bytes::hex2array::<_, 32>(public_key_str);
let account_id_20 = array_bytes::hex2array::<_, 20>(public_key_str);

If you want AccountId you'd better define a trait and implement it in the runtime level.

Because the pallet doesn't know your AcccountId type. You don't know how many bytes that you should take.

// pallet
pub trait Config {
  type Str2AccountId: Str2AccountId,
}

pub trait Str2AccountId {
  type AccountId;

  fn str2accountid(public_key_str: &str) -> Self::AccountId;
}

impl<T> Pallet<T>
where
  T: Config
{
  fn example(public_key_str: &str) {
    let account_id = T::StrToAccountId::str2accountid(public_key_str);
  }
}

// runtime
pub struct StrToAccountId;
impl pallet::StrToAccountId for StrToAccountId {
  type AccountId = AccountId32;

  fn str2accountid(public_key_str: &str) -> Self::AccountId {
    array_bytes::hex2array::<_, 32>(public_key_str)
  }
}

impl pallet::Config for Runtime {
  type StrToAccountId = StrToAccountId;
}
3
  • But this is an AccountId32, not an AccountId Feb 8, 2023 at 16:12
  • Updated my answer. Feb 8, 2023 at 16:29
  • Do you know any method to transform an ss58 to pubkey in runtime? Feb 8, 2023 at 18:57
0

If you have the representation in ss58 format already check this old answer on StackOverflow: https://stackoverflow.com/a/66075924/5964038

let account_id: AccountId = AccountId::from_ss58check("AccountSs58Format").unwrap()

In case you have the hex representation and want the AccountId, check this old answer from StackOverflow too: https://stackoverflow.com/questions/60983883/how-to-encode-the-hex-string-representation-of-an-account-id-in-substrate-using

let account: AccountId32 = hex_literal::hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"].into();

And then get the ss58-check string with to_ss58check().

Check the functions of the ss58 codec library here.

3
  • I didn't write this method because from_ss58check requires std. So, I think he can not use this in the pallet. :) Feb 8, 2023 at 12:53
  • And hex_literal::hex! requires a string literal. I prefer to use array-bytes. :) Feb 8, 2023 at 12:55
  • True, for the pallet your response makes more sense than the from_ss58check
    – Alex Bean
    Feb 8, 2023 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.