Using the Substrate blockchain framework, how can I convert between Substrate specific types and Rust primitive types and vice versa?
For example:
- Convert a time (
T::Moment
) to au64
- Convert a u64 to a
T::Balance
etc...
Substrate and Polkadot Stack Exchange is a question and answer site for developers building blockchains with the Substrate SDK. It only takes a minute to sign up.
Sign up to join this communityUsing the Substrate blockchain framework, how can I convert between Substrate specific types and Rust primitive types and vice versa?
For example:
T::Moment
) to a u64
T::Balance
etc...
For most Substrate specific types like BlockNumber
, Balance
, Nonce
, etc... we guarentee that these types use a u32
with the AtLeast32Bit
trait.
From the trait BaseArithmetic
, the following are implemented:
From
: u8
, u16
, u32
TryFrom
: u64
, u128
, usize
TryInto
: u8
, u16
, u32
, u64
, u128
, usize
Another trait is also provided to provide ergonomic infallible conversion when you don't care if the value saturates.
UniqueSaturatedInto
: u8
, u16
, u32
, u64
, u128
UniqueSaturatedFrom
: u64
, u128
NOTE on
SaturatedConversion
SaturatedConversion
(saturated_into
andsaturated_from
) should not be used unless you know what you're doing, you've thought and considered all options and your use-case implies that saturation is fundamentally correct. The only time I imagine this is the case is deep in runtime arithmetic where you are logically certain it will not overflow, but can't provide a proof because it would depend on consistent pre-existing state.
This means that working from u32
to Substrate specific types should be easy:
pub fn u32_to_balance(input: u32) -> T::Balance {
input.into()
}
For larger types, you need to handle the case where the Balance
type for a runtime is smaller than what is available:
pub fn u64_to_balance_option(input: u64) -> Option<T::Balance> {
input.try_into().ok()
}
// Note the warning above about saturated conversions
pub fn u64_to_balance_saturated(input: u64) -> T::Balance {
input.saturated_into()
}
When converting from T::Balance
to a rust primitive, you need to also handle conversion between incompatible types:
pub fn balance_to_u64(input: T::Balance) -> Option<u64> {
TryInto::<u64>::try_into(input).ok()
}
// Note the warning above about saturated conversions
pub fn balance_to_u64_saturated(input: T::Balance) -> u64 {
input.saturated_into::<u64>()
}