Git Product home page Git Product logo

recipes's Introduction

Substrate Recipes ๐Ÿด๐Ÿ˜‹๐Ÿด

Build Status

Lines of Code Try on playground

A Hands-On Cookbook for Aspiring Blockchain Chefs

Get Started

Ready to roll up your sleeves and cook some blockchain? ๐Ÿ˜‹

Repository Structure

There are five primary directories in this repository:

  • Text: Source of the book written in markdown. This text describes the code in the other three directories.
  • Pallets: Pallets for use in FRAME-based runtimes.
  • Runtimes: Runtimes for use in Substrate nodes.
  • Consensus: Consensus engines for use in Substrate nodes.
  • Nodes: Complete Substrate nodes ready to run.

The book is built with mdbook and deployed via github pages.

Building This Book Locally

Building the book requires mdBook, ideally the same version that rust-lang/rust uses in this file. To get it:

$ cargo install mdbook --vers [version-num]

To build the book, type:

$ mdbook build

The output will be in the book subdirectory. To check it out, open up book/index.html in a web browser, or to serve the book locally, type:

$ mdbook serve

The default address to view the book will be located at http://localhost:3000 .

License

The Substrate Recipes are GPL 3.0 Licensed It is open source and open for contributions.

Using Recipes in External Projects

The pallets and runtimes provided here are tested and ready to be used in other Substrate-based blockchains. The big caveat is that you must use the same upstream Substrate version throughout the project.

recipes's People

Contributors

4meta5 avatar andor0 avatar apopiak avatar ashwhitehat avatar bertstachios avatar boneyard93501 avatar brenzi avatar cimm avatar danforbes avatar dependabot[bot] avatar fishmonger45 avatar herou avatar honeywest avatar iczc avatar igorline avatar jeluard avatar jimmychu0807 avatar joshorndorff avatar juniuszhou avatar kaichaosun avatar mkdior avatar nuke-web3 avatar ppoliani avatar seunlanlege avatar shawntabrizi avatar shirshak55 avatar tripleight avatar vedant1811 avatar waylandc avatar wheresaddie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

recipes's Issues

srml/support traits

  1. Under the Module Menu section, I want to include more of the examples in the existing module documentation (the root file for each SRML module)

  2. I want to demonstrate implementations for more traits in srml_support to show how to abstract out the SRML logic into stand-alone Substrate runtimes.

(1) and (2) should probably be in the same section.

fix links to new substrate dev hub

there's a few links, like the one in intro/motivation to Gautam's TCR tutorial that point to the old substrate website; also advanced/safety recipe links to Gautam's best practices

failed to select a version for `substrate-client` which could resolve this conflict

I am following this tutorial.

./scripts/init.sh works fine.

When I try to run cargo build --release, I get this error.

error: failed to select a version for `substrate-client`.
    ... required by package `super-runtime v2.0.0 (/Users/dhruvinparikh/blockx-labs/recipes/kitchen/runtimes/super-runtime)`
    ... which is depended on by `kitchen-node v2.0.0 (/Users/dhruvinparikh/blockx-labs/recipes/kitchen/node)`
versions that meet the requirements `*` are: 2.0.0

the package `super-runtime` depends on `substrate-client`, with features: `std` but `substrate-client` does not have these features.


failed to select a version for `substrate-client` which could resolve this conflict

Translations

Language Accessibility

  • Spanish
  • Portuguese
  • Chinese
  • Korean
  • Japanese

ci build for recipes

  • start configuring node template in kitchen with permutations of example modules
  • show build status (for each module) + a description on the kitchen README

generating randomness

Mechanisms for generating randomness offer varying levels of security/cost. Random seed is inexpensive but not very secure; VRFs are more expensive and more secure. Likewise, a recipe on randomness should guide developers based on the requirements of their application to navigate this tradeoff between runtime cost and security requirements...

recipes/long-tutorials

NFT Ticket Machine

initially described in #42

Basically, make a prototype of mintbase or kickback using the Substrate Collectables Workshop (kitties v2).

Consider using IPLD data structures in the context of NFT standard fields?

Polkadot-JS Apps does not work with Kitchen Node

Then the App pretty much stuck...

I think we can:

  1. by default comment out all additional modules, and introduce the necessary type definition to make the module code with polkadot-JS Apps. Have one section teaching readers to add type def. in polkadot-JS Apps

  2. Have a big blob of type at the end of ch3 and ask readers to add to the type def. in order to interact with the module code from the Apps.

Example of using Signed Extension

This topic came up during SCL today.

Some possible example scenarios.

A transaction should only be valid:

  • after a certain block height
  • before a block height
  • after/before a timestamp
  • in blocks with an even height
  • in blocks with an even hash

Storage::Off-Chain

This solid OffChain Workers explainer by Gautam has got me thinking about how storage patterns will change as things improve.

I want to eventually do an explainer on optimizing storage by keeping most data off-chain -- and combine this with a tutorial on properly using off-chain workers.

srml-panic

We discussed this once briefly with @shawntabrizi in person.

Briefly said: create a simple runtime which is a collection of

All the things that you should NOT do
All the things that could go wrong, will go wrong.
(bonus) Demonstrate how you reach a corrupt state or fault or exploit etc.

Some ideas quickly:

  • float
  • vec which is appendable, for free, by user.
  • write then check
  • panic if corrupted data.
  • change data type via an upgrade (not sure how it can be faulty but worth investigating)

Ring Buffer

In srml/system/src/lib.rs, there is a circular buffer pattern that seems useful. *note that you can also use vec_dequeue

decl_storage {
  /// Series of block headers from the last 81 blocks that acts as random seed material. This is arranged as a
		/// ring buffer with the `i8` prefix being the index into the `Vec` of the oldest hash.
		RandomMaterial get(random_material): (i8, Vec<T::Hash>);
}
...

fn initialize {
<RandomMaterial<T>>::mutate(|&mut(ref mut index, ref mut values)| if values.len() < 81 {
			values.push(parent_hash.clone())
		} else {
			values[*index as usize] = parent_hash.clone();
			*index = (*index + 1) % 81;
		});
}

This is useful when you need to maintain a finite size set that requires replacing old elements with new data as the blockchain grows (which seems like an obviously useful pattern, especially for block explorers).

Add a section on explaining how to integrate module into node and start up your chain

After reading ch4.1, from a new-comer perspective, yes, I would be able to build the module, but then how do I play with the module I have just built? How could I make it run on a chain?

Maybe between ch 3 & 4, add a section documenting how to integrate the module-template into node-template, start up the chain, and then using polkadot UI connecting to our locally-running node, and play with it.

@4meta5
I was contemplating adding this for a while, but preferred just linking to other tutorials that walk through this process...it would be great to have it in the recipes though in a succinct, generic form so that people could use it as a reference like the rest of the recipes

@shawntabrizi
would you think it is worthwhile to add a section about this?

Res:

kitchen/runtime compilation error

getting two errors when I compile kitchen/runtimes/super-node-runtime && kitchen/runtimes/super-node-genesis

error[E0432]: unresolved import `babe::SameAuthoritiesForever`
  --> /Users/4meta5/core/recipes/recipes/kitchen/runtimes/super-node-runtime/src/lib.rs:20:35
   |
20 | use babe::{AuthorityId as BabeId, SameAuthoritiesForever};
   |                                   ^^^^^^^^^^^^^^^^^^^^^^ no `SameAuthoritiesForever` in the root

error[E0437]: type `EpochChangeTrigger` is not a member of trait `babe::Trait`
   --> /Users/4meta5/core/recipes/recipes/kitchen/runtimes/super-node-runtime/src/lib.rs:206:2
    |
206 |     type EpochChangeTrigger = SameAuthoritiesForever;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `babe::Trait`

error: aborting due to 2 previous errors

This type exists and is a member of babe::Trait so I don't know why I'm getting this error. @JoshOrndorff do you know?

EDIT: This is worked around by #64 on master, but it remains a mystery, but the babe code in this module only compiles when it is mismatched with the code on upstream Substrate.

governance recipes

patterns/recipes

  • module instancing in collective -- PR 3041 (and balances)
  • special origin type in collective => reference polkadot EnsureParachain
  • floating point arithmetic in inflation.rs in staking -- PR 3048, 2882

Governance Walk Through (put drafts in book and migrate to substrate.dev/docs)

  • kusama genesis config (and genesis configs in general)
  • phragmen in staking
  • inflation in staking
  • treasury => reference parachain para_id "factory"
  • collective + elections => council
  • scored membership
  • generic asset

Allow importing modules or runtimes from git

One nice way to experiment with the modules and runtimes in the recipes would be by depending on the from Cargo.toml For example, when I created a node to house the super-node-runtime (drafted here) I used this line in Cargo.toml

[dependencies.node-template-runtime]
path = "../recipes/kitchen/runtimes/super-node-runtime"

It would be nicer to use

[dependencies.node-template-runtime]
git = "https://github.com/substrate-developer-hub/recipes.git"
branch = "master"

I believe this can be achieved through cargo workspaces https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html

@4meta5 Is this something you're interested in having? If not feel free to close this issue.

Fix section on Storage Recipes/Single Value.

On the Storage Recipes/Single Value section (https://substrate.dev/recipes/storage/value.html), at the very bottom, there's a paragraph about Substrate Specific Types. It only says that "to access the Substrate types Hash, AccountId, and Balance, it is sufficient to inherit the balances module". Ideally, it should demonstrate how to access these types using the system module, instead of requiring users to use the balances module.

Incentivizing OSS Contributions

I'm keen to experiment with OSS incentives beyond just listing github handles on the README (though that might be sufficient; I acknowledge that overdoing it with incentives is worse than basic recognition)

Brainstorming

1. Gitcoin or Bounties Network, but I don't really have the funds ATM...
2. Harberger Ad board with rent issued according to contributions; this could be attractive to projects working on Substrate -- they abstract out patterns from their project, PR them here, and then achieve temporary advertising to attract OSS contributions to their project
3. Establishing an Aragon DAO to manage this repo with voting rights issued according to contributions

For (1), I could set up a DAO like MolochDAO (or soon SunshineDAO) to accept donations, issue proportional voting rights, and fund grants for specific recipes. As a reminder, grant funding is voted on by the donors that choose to request shares (and shares provide the voting rights).

The problem with (2) and (3) is that weighting the value-add of contributions is extremely subjective. I still don't think this means we can't experiment!

srml-treasury

  • similar to this recipe but explain spend_funds method in context of T::SpendPeriod::get()
  • use of Imbalances type
  • use of OnDilution type

more?

extending treasury to accept grant applications (based on this)

cargo build --release does not properly build kitchen node

Just tried following instructions to run a kitchen node.
https://substrate.dev/recipes/base/runnode.html

However seem to get the following error when running cargo build --release

Error:

araa@MAC127 ~/Desktop/recipes/kitchen/node (master) (โ‚ฟ) cargo build --release
    Updating git repository `https://github.com/paritytech/substrate.git`
    Updating crates.io index
error: no matching package named `srml-babe` found
location searched: https://github.com/paritytech/substrate.git
required by package `super-runtime v2.0.0 (/Users/araa/Desktop/recipes/kitchen/runtimes/super-runtime)`
    ... which is depended on by `kitchen-node v2.0.0 (/Users/araa/Desktop/recipes/kitchen/node)`

Fixed Point Arithmetic

This is a subtle difficulty when working with computers. Floating point arithmetic is nondeterminisic so the basic approach is to use a wrapper type that represents either 1_000_000 (Permill) or 1_000_000_000 (Perbill) times the given floating point value.

I've learned recently that this can get messy. I think it's worth doing a recipe on this.

loosely coupled modules (kitchen/runtime/**)

loosely coupled module examples in kitchen/runtime/; the super-runtime from #52 does the job at the moment (#29) so this isn't a priority unless someone wants to add it

Something like @JoshOrndorff 's state-changer or marketplace would be useful for demonstrating runtime configuration in practice with only a few modules.

The justification is that developers might start with one module for an MVP and then gradually abstract certain behavior out into separate modules which still need to be configured in one runtime.

Build and test modules with ci

We've agreed in riot that running CI over the modules (and eventually the runtimes and the node) is a good idea. Even before runtime tests are written for the modules, we can at least use CI to ensure they build.

Options for CI pipeline and their strengths are
Travis -- Already used for mdbook portion of recipes
Circle -- Already used by this team for devhub and frontend template
Github actions -- No 3rd party service needed. All stays here in github.

init runtime section

Runtime configuration is something that the book ignores thus far, but module development only makes sense in the context of a Substrate runtime. So, it is necessary to add a new section called Runtime.

  • super runtime (kitchen/runtimes/super-runtime)
  • node for runtimes (kitchen/node)

Fix Typo

storage/list/linked_map heading

Vision for Substrate Recipes (v2)

WHAT ARE THE RECIPES? I envision the recipes as similar to Rust by Example, but for Substrate. The purpose is to provide examples of Substrate runtime patterns through minimal samples. Each sample might only take up a single page in the book, but the point is to demonstrate common patterns and application in the context of an example.

TLDR; each recipe should fulfill two objectives:

  • demonstrate Substrate runtime best practices (full code should be tested and placed in kitchen/)
  • show the usefulness of the pattern in the context of an example

motivation:

While some developers complete tutorials chronologically, many prefer to skim tutorials for usage examples and apply patterns to build a personal project. For these developers, it is useful to have something like Rust by Example to reference while building. By not requiring the developer to read previous sections for continuity, this format is convenient in the context of fast prototyping based on common design patterns.

If done well, this format can

  1. provide high signal to noise for mature developers building on Substrate
  2. reduce the friction to publish high-level explanations for code in the SRML

The 2nd objective is especially relevant. I want to minimize the friction for converting personal notes into recipes for teaching others. Moreover, I want to target the creation of specific content pertaining to the most well-vetted code that uses the Substrate Runtime API, the SRML.

srml-tour

With @JoshOrndorff 's blessing, I want to create a section similar to srml-tour for the recipes. I think this fits what I view as the purpose of the recipes: a space to share high-level explanations of SRML code and API usage examples for building runtimes.

criteria

The structure of each recipe should be oriented around the patterns and use cases it exposes. Even so, in general, each recipe should be a single page explainer to communicate how the code in certain module(s) maps to the web3 research specs. Each post should do the following

  • motivate study of the chosen module(s) (possibly in the context of Polkadot)
  • explain how objects/relationships are modeled and how this influences the implementation
  • extract any useful patterns and discuss examples for usage in other runtime samples

priorities

  • treasury, especially because of this
  • democracy, already partly finished by @JoshOrndorff
  • collective + elections as the council
  • support/phragmen => elections + staking
  • staking because it contains inflation which is interesting paired with treasury and demonstrates fixed point arithmetic

future recipes/sections?

lots of V2 patterns to be covered...

  • fixed point arithmetic, see 3456, 3189
  • runtime module configuration, see 29
  • testing and error handling => not lengthy docs, but succinct tips and short examples of scaffolding (3433 and 3479)

overflow/underflow management

To deal with a subtraction overflow, Kian used an interesting pattern in the calculation of a transaction fee multiplier; it is worth reviewing for other people that may come across the same problem. The naive solution would be to use a signed integer instead of an unsigned one, but this is even cleaner:

let diff = match ideal.checked_sub(all) {
			Some(d) => d,
			None => { positive = true; all - ideal }
};

Basically, if it didn't work, we reversed the order of computation, then subtracted the term instead of added it. We could tell if it needed to be substracted by the value of positive = all > ideal.

braindump

make a separate issue for each of these if/when pursued

  • proof of existence (shawn's example)
  • off-chain storage section in Storage (could include caching, database interaction, etc)
  • cryptography (2phase commit, blind auctions, hashing data, zk stuff, extra layers of encryption e.g. PRE)
  • private network setup (by Josh and Gautam)
  • rust-unofficial patterns in the context of Substrate samples?

Generalized Child Tries (storage)

Demonstrate usage of trie storage structure in the context of a minimal example

Rob: "What we're doing there is storing the root of another trie under a key in the main trie. Since keys are typically hashed in the main trie, it's a fairly convenient (although not the only) way to make sure that inserting many elements under a single mapping does not make your typical lookup path for unrelated elements longer."

cc @shawntabrizi

srml-democracy

High-level overview of how srml-democracy coordinates the public referenda for Substrate-based governance. Might be useful to discuss conviction voting and the Approved trait for setting vote thresholds.

Feel free to discuss how we could edit the VoteThreshold struct and still match on it to add more thresholds and, therefore, change the number of outcomes or the weighting of the voting algorithm itself. Then, how could the network be elegantly governed through this upgrade?

criteria from #32

The structure of each recipe should be oriented around the patterns and use cases it exposes. Even so, in general, each recipe should be a single page explainer to communicate how the code in certain module(s) maps to the web3 research specs. Each post should do the following

  • motivate study of the chosen module(s) (possibly in the context of Polkadot)
  • explain how objects/relationships are modeled and how this influences the implementation
  • extract any useful patterns and discuss examples for usage in other runtime samples

hash function usage docs

how to choose which hash function to use for double_map and/or other things in the srml

  • what are the options
  • when is each option preferred (associated tradeoffs)

Recipes v2.0 Live Stream

I will live stream the creation of all the recipes using v2.0 of Substrate.

Here is a starting list of ideas to create; organization TBD:

  • type-conversions

    • Balance to u64
    • Moment to u64
    • AccountId to Hex/Public Key
    • more?
  • Custom Types (multiple projects)

    • enum
    • struct
  • Limiting Vec input size

  • Two Modules Interacting

  • Static Getters (rather than using storage) and exposing it in metadata

  • All storage types

    • StorageValue
    • StorageMap
    • LinkedMap
    • DoubleMap
  • Creating Origins, using all origins

  • Runtime Hooks

  • [ ]

  • [ ]

Explain lib.rs integrations

As a suggestion, it may be useful to explicitly mention the necessary changes to lib.rs for each recipe. That way, readers can follow along personally with the code snippets.

Example: In this page (https://substrate.dev/recipes/storage/constants.html), it could show something like:

parameter_types! {
	pub const Number: u32 = 5;
}

/// Used for the module template in `./template.rs`
impl template::Trait for Runtime {
	type Event = Event;
	type Number = Number;
}

Move content to Docusaurus

This is just a suggestion, but it may make sense to have this content migrated to Docusaurus.

@4meta5, are there advantages to using RustDoc for these recipes?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.