JoshOrndorff / substrate-recipes

A Hands-On Cookbook for Aspiring Blockchain Chefs
GNU General Public License v3.0
380 stars 184 forks source link

How-to on basics of primative types in runtime development #403

Open nuke-web3 opened 3 years ago

nuke-web3 commented 3 years ago

There is common misunderstanding of why you can't use very common types, mostly String in runtime developments

Here are some examples: 1 , 2

I would propose that somewhere (maybe in recipes, but totally open to another location) we have an explainer of no_std use and what that means for runtime dev, as well as a few examples of how to do storage formally and what best practices are for this.

e.g. encoding strings in UTF8 by a Vec<u8> struct, and examples of how to encode/decode this.

nuke-web3 commented 3 years ago

In addition / alternatively, this can live on stackoverflow. https://stackoverflow.com/questions/65348505/runtime-building-string-not-found-in-this-scope

I would appreciate some help in answering this properly in this issue before posting an answer there 🙏🏼

danforbes commented 3 years ago

Thank for creating this Issue, @NukeManDan! Just want to note that I think @bkchr stated this is not related to the no_std requirement in any way, but is instead a best practice to encourage minimal storage requirements - storing strings in the runtime is a "code smell".

Edit: Basti also suggested storing the hash of strings on-chain while storing the strings themselves off-chain.

nuke-web3 commented 3 years ago

Right, best practice for large items should be done with off-chain storage and mapped hashes (IPFS CIDs) stored. But many starting out will run into this kind of error, experimenting. This is a chance to guide them to this conclusion.

There will also be some times that String might be appropriate as an approach, or other larger storage items... what is best practice here if you deem you need this kind of thing? and how would you go about assessing that?

Where abouts do we explain no_std features and things to watch for specific to substrate dev in our docs?

danforbes commented 3 years ago

Where abouts do we explain no_std features and things to watch for specific to substrate dev in our docs?

https://substrate.dev/docs/en/tutorials/add-a-pallet/import-a-pallet

Edit: with respect to your first set of questions, I think we try to cover these ideas here

what is best practice here if you deem you need this kind of thing? and how would you go about assessing that?

https://substrate.dev/docs/en/knowledgebase/runtime/storage#what-to-store

shawntabrizi commented 3 years ago

The top level answer to your issue is that we support any type, not matter how complex, as long as it is supported by Parity SCALE Codec. You also have to remember that Parity SCALE Codec is not a Rust specific codec format. It must be implementable by any other programming language. So if Rust has some really unique abstract types which only exist in the context of Rust, we would not support it in SCALE or in the runtime.

AFAIK, all reasonable primitive types are supported, except string, which as I mentioned here, is an explicit choice made since honestly Strings are not as simple as people would think.