Substrate - cannot find type `Vec` in this scope

Viewed 562

I'm trying to play around with the substrate node template example and add some custom structs around.

However, I get the following compilation error:

"cannot find type Vec in this scope"

And example of the struct being used (+ associated traits and where I'm importing them from) is:

    use codec::{Encode, Decode};
    use scale_info::TypeInfo;

    // , WrapperTypeDecode, WrapperTypeEncode, TypeInfo
    #[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo)]
    #[cfg_attr(feature = "std", derive(Debug))]
    pub struct Image {
        // Note: Consider changing to JPG compression in the future
        pixels: Vec<Vec<(u8, u8, u8)>>,
        height: u32,
        width: u32
    }

But given that substrate requires quite a lot of bootstrapping I can't provide a working example.

The one thing I tried is adding #[cfg(feature = "std")] which afacit should have enabled either the rust std or the std defined in the Cargo.toml, I'm honestly unsure which. But it didn't help.

My main question is... how do I fix this? What imports am I missing where?

My secondary more important question is why would this be happening? Inside the https://docs.substrate.io/tutorials/v3/kitties/pt1/ tutorial vec! and Vec seem to be used without any issues or further additions... Or rather, the one addition I see is #[cfg(feature = "std")] being used before all impl blocks that use vec! but not before using Vec. Why is this the case? Is this simply allowing a block to import anything from the rust std? Or does it refer to the std defined in the Cargo.toml ? Why would it be necessary for vec! but not Vec ?

4 Answers

Have a look at CRUST parachain, https://github.com/paritytech/substrate-lfs or other web3 / IPFS off-chain storage mechanisms.

Generally you want to store as little state on-chain as possible. Storing the image data directly (even as a highly compressed jpeg) would probably not be a great design decision as it could get very expensive (unless your image sizes are very small).

First of all you don't want to enable std when you are working with substrate, as non-std is required by SCALE codec, this also enables wasm compilation. More on SCALE here

About Vec, you might be just lacking using some frame_support crate, not much that I can tell just for checking the struct you provided. But I will let you here the storage entry about runtime storage of the substrate docs. And would recommend to compare your code with some pallet on the substrate repo so you can see from other pallets using Vec what you might be missing. For instance, nicks pallet stores the nick itself as a Vec so that could be a good place to start looking.

Hope this is helpful enough.

What #[cfg(feature = "std")] does is "if the Cargo feature of my crate called std is enabled, include the code block below. This is a form of conditional compilation. Apparently substrate needs to build the code in no-std contexts too. The parts that need to run in no-std won't be able to use Vec.

I solved it by adding default-features = false, in my dependencies in my runtime/Cargo.toml

pallet-evm = { git = "https://github.com/paritytech/frontier", default-features = false, branch = "polkadot-v0.9.25" }
Related