1
  • I'm building a dApp and would like to treat the contract address as a String.
  • I was able to find a way to convert a String to an AccountId, but no example exists for the reverse case.
  • I also tried encoding with "parity-scale-codec" as shown below, but it is not guaranteed to be UTF-8, so it cannot be converted to String.

If anyone knows how to convert please help.

        #[ink(message)]
        pub fn convert_accountid_to_string(&self, account_id: AccountId) -> Vec<u8> {
            let tmp :Vec<u8> = account_id.encode();
            tmp
        }

  • I implemented the following as advised, but got some errors and don't know how to work around it,

Source Code:

        #[ink(message)]
        pub fn convert_accountid_to_string2(&self, account_id: AccountId) -> String {
            let account_id = H256::from(account_id);

            // Convert the AccountId to an SS58 encoded string
            let account_id_string = account_id.to_ss58check();
            account_id_string
        
        }

Error Information:

error[E0277]: the trait bound `H256: From<ink::ink_primitives::AccountId>` is not satisfied
  --> /Users/shin.takahashi/develop/work/account_id_test/lib.rs:39:41
   |
39 |             let account_id = H256::from(account_id);
   |                              ---------- ^^^^^^^^^^ the trait `From<ink::ink_primitives::AccountId>` is not implemented for `H256`
   |                              |
   |                              required by a bound introduced by this call
error[E0599]: no method named `to_ss58check` found for struct `H256` in the current scope
  --> /Users/shin.takahashi/develop/work/account_id_test/lib.rs:42:48
   |
42 |             let account_id_string = account_id.to_ss58check();
   |                                                ^^^^^^^^^^^^ method not found in `H256`
2
  • let account_id = H256::from([1u8; 32]);
    – kayvan jam
    Commented Apr 29, 2023 at 5:15
  • use ink_env::AccountId; use sp_core::H256; use core::convert::From; impl From<AccountId> for H256 { fn from(account_id: AccountId) -> Self { let mut h256 = H256::default(); h256.as_mut().copy_from_slice(&account_id[..]); h256 } }
    – kayvan jam
    Commented Apr 29, 2023 at 6:27

3 Answers 3

3

If you don't care about SS58 format (which will be costly operation) and just want a string, then why not convert it to hex string? It will be a very cheap operation.

Add hex crate to Cargo.toml like this

[dependencies]
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
#[ink::contract]
mod contracts {
    use ink::{
        prelude::string::String,
    };
    
    // ...

    impl Contracts {
        #[ink(message)]
        pub fn account_to_string(&self, account: AccountId) -> String {
            hex::encode(account)
        }
    }

    // ...
}

The output will be like this "d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"


Adding to kayvan's answer here (I can't post comments yet)

The default ink! AccountId has AsRef<[u8;32]> implementation, you can use that to fix your H256 conversion error.

        #[ink(message)]
        pub fn convert_accountid_to_string2(&self, account_id: AccountId) -> String {
            // convert to &[u8;32] first
            let account_id: &[u8;32] = account_id.as_ref();
            let account_id = H256::from(account_id);

            // Convert the AccountId to an SS58 encoded string
            let account_id_string = account_id.to_ss58check();
            account_id_string
        
        }

EDIT: This will not work inside ink! (wasm32 target as it needs std), use hex approach if you just want a string

4
  • Thank you for your help. But your code does not work. I got an error. "error[E0599]: no method named to_ss58check found for struct H256 in the current scope". Do you know how to solve this ? Commented Apr 29, 2023 at 9:17
  • This is my test repositry using ink!4.0. github.com/realtakahashi/account_id_test Commented Apr 29, 2023 at 9:19
  • 1
    Hi Takahashi I've just gone through the sp_core::crypto code and it is apparent you cannot use ss58Codec trait inside ink! as it requires std and ink! (wasm) does not allow that github.com/paritytech/substrate/blob/… As I said in my answer above, if you simply want to convert the AccountId to string, use the hex approach, it's much more simple and very efficient computation wise (gas efficient also). Commented Apr 29, 2023 at 10:52
  • Hi. Ashutosh! Thanks to you, I was able to implement. I post my code as my answer. Commented May 1, 2023 at 0:16
0

you can convert an AccountId to a string using the ss58 crate. First, add the ss58 crate to your Cargo.toml dependencies:

[
dependencies
]
ss58 = "0.3.0"

Then, you can use the ss58::Ss58 trait to convert an AccountId to a string. Here's an example:

use sp_core::crypto::Ss58Codec;
use sp_core::H256;

fn main() {
    // Assuming you have an AccountId instance
    let account_id = H256::from([/* your 32-byte array representing the AccountId */]);

    // Convert the AccountId to an SS58 encoded string
    let account_id_string = account_id.to_ss58check();

    println!("AccountId as a string: {}", account_id_string);
}

This will convert the AccountId to an SS58 encoded string, which is the standard format for representing Substrate addresses as strings.

1
  • Thank you for your help. But I got some errors. I will include the error information in the question, so could you help me? Commented Apr 29, 2023 at 2:49
0
  • I finally implemented the code below. Make AccountId a string with hex. Then enter that string to restore the AccountId.
        #[ink(message)]
        pub fn convert_accountid_to_hexstring(&self, account_id: AccountId) -> String {
            hex::encode(account_id)
        }

        #[ink(message)]
        pub fn convert_hexstring_to_accountid(&self, hex_string:String) -> Option<AccountId> {
            match hex::decode(hex_string) {
                Ok(value) => {
                    let mut array = [0; 32];
                    let bytes = &value[..array.len()];
                    array.copy_from_slice(bytes);
                    let account_id: AccountId = array.into();
                    return Some(account_id);
                },
                Err(_) => None,
            }
        }

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.