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 at 16:12
  • Updated my answer. Feb 8 at 16:29
  • Do you know any method to transform an ss58 to pubkey in runtime? Feb 8 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 at 12:53
  • And hex_literal::hex! requires a string literal. I prefer to use array-bytes. :) Feb 8 at 12:55
  • True, for the pallet your response makes more sense than the from_ss58check
    – Alex Bean
    Feb 8 at 13:27

Your Answer

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

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