2

I am a Rust and Ink! novice so please bear with me but, I have a struct that looks like the following:

#[ink(storage)]
pub struct Contract {
    test: sp_arithmetic::FixedU128,
}

Unfortunately, I unable to build this project because of the following errors:

the trait bound FixedU128: SpreadLayout is not satisfied the following other types implement trait SpreadLayout

the trait bound FixedU128: StorageLayout is not satisfied the following other types implement trait StorageLayout

For the smart contract project I am working on, I really need to use fixed points. What is the recommended way to solve this issue? To create some wrapper that implements the above traits? If yes, are there any good tutorials for that?

Thank you very much in advance for your time!

0

3 Answers 3

3

You can store it in the storage as a Vec<u8>, in the function you can decode the FixedU128, and when you want to store the value, you can encode it.

The problem is that the type does not implement the SpreadLayout, which must be implemented for the contract storage struct (therefore for all its members as well).

1
  • 1
    Thank you! Figured it out based on your comments. For anyone interest, please see my comment below.
    – eleidon
    Commented Nov 11, 2022 at 0:52
3

Thanks to Coreggon, I figured it out. I wasn't able to decode it to a Vec<u8> and vice versa but thankfully FixedU128 also implements CompactAs: https://docs.rs/parity-scale-codec/3.0.0/parity_scale_codec/trait.CompactAs.html#tymethod.encode_as

A sample solution:

use sp_arithmetic::{FixedU128};
use scale::CompactAs;

#[ink(storage)]
pub struct Contract {
    test_compact: u128,
}

impl Contract {
    fn get_test(&self) -> FixedU128 {
        let res = FixedU128::decode_from(self.test_compact);
        return res.unwrap();
    }

    fn set_test(&mut self, new_test: FixedU128) {
        self.test_compact = *new_test.encode_as();
    }
}
1
#![cfg_attr(not(feature = "std"), no_std)]

use ink_lang as ink;

#[ink::contract]
mod test {
use scale::Encode;
use sp_arithmetic::FixedU128;
use ink_prelude::vec::Vec;


#[ink(storage)]
// #[derive(Encode, Decode)]
pub struct Test {
    test: Vec<u8>,
}

impl Test {
    #[ink(constructor)]
    pub fn new() -> Self {
        Self {test: Default::default() }
    }

    #[ink(constructor)]
    pub fn default() -> Self {
        Self::new()
    }

    #[ink(message)]
    pub fn fixed_point_function(&mut self) {
        // self.test = vec![FixedU128::from_float(0.1515151f64)]
        let fixed_point = FixedU128::from_float(0.1515151f64).encode();
        self.test = fixed_point;
    }
}
}
2
  • 1
    @Coreggon are you talking something like this?
    – go11li
    Commented Nov 9, 2022 at 11:43
  • @Coreggon while build this code I get those errors. error: the #[alloc_error_handler] in ink_allocator conflicts with allocation error handler in: std error[E0463]: can't find crate for panic_abort
    – go11li
    Commented Nov 10, 2022 at 0:20

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.