-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b6c92fa
commit 5c461a2
Showing
10 changed files
with
3,916 additions
and
130 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "pallet-kitties" | ||
version = "0.1.0" | ||
description = "An NFT Marketplace for Kitties" | ||
authors = ["Shawn Tabrizi <[email protected]>"] | ||
homepage = "https://www.shawntabrizi.com/substrate-collectables-workshop/" | ||
repository = "https://github.com/shawntabrizi/substrate-collectables-workshop" | ||
edition = "2021" | ||
publish = false | ||
|
||
[package.metadata.docs.rs] | ||
targets = ["x86_64-unknown-linux-gnu"] | ||
|
||
[dependencies] | ||
codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = ["derive"] } | ||
scale-info = { version = "2.11.1", default-features = false, features = ["derive"] } | ||
frame = { package = "polkadot-sdk-frame", version = "0.6.0", default-features = false, features = ["experimental", "runtime"] } | ||
|
||
[features] | ||
default = [ "std" ] | ||
std = [ "codec/std", "frame/std", "scale-info/std" ] | ||
try-runtime = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Basic | ||
edition = "2021" | ||
hard_tabs = true | ||
max_width = 100 | ||
use_small_heuristics = "Max" | ||
# Imports | ||
imports_granularity = "Item" | ||
reorder_imports = true | ||
# Consistency | ||
newline_style = "Unix" | ||
# Misc | ||
chain_width = 80 | ||
spaces_around_ranges = false | ||
binop_separator = "Back" | ||
reorder_impl_items = false | ||
match_arm_leading_pipes = "Preserve" | ||
match_arm_blocks = false | ||
match_block_trailing_comma = true | ||
trailing_comma = "Vertical" | ||
trailing_semicolon = false | ||
use_field_init_shorthand = true | ||
# Format comments | ||
comment_width = 100 | ||
wrap_comments = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use super::*; | ||
use frame::prelude::*; | ||
|
||
impl<T: Config> Pallet<T> { | ||
pub fn mint(owner: T::AccountId) -> DispatchResult { | ||
Self::deposit_event(Event::<T>::Created { owner }); | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
mod impls; | ||
|
||
use frame::prelude::*; | ||
pub use pallet::*; | ||
|
||
#[frame::pallet(dev_mode)] | ||
pub mod pallet { | ||
use super::*; | ||
|
||
#[pallet::pallet] | ||
pub struct Pallet<T>(core::marker::PhantomData<T>); | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config { | ||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>; | ||
} | ||
|
||
#[pallet::event] | ||
#[pallet::generate_deposit(pub(super) fn deposit_event)] | ||
pub enum Event<T: Config> { | ||
Created { owner: T::AccountId }, | ||
} | ||
|
||
#[pallet::error] | ||
pub enum Error<T> {} | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
pub fn create_kitty(origin: OriginFor<T>) -> DispatchResult { | ||
let who = ensure_signed(origin)?; | ||
Self::mint(who)?; | ||
Ok(()) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,69 @@ | ||
# Polkadot-SDK | ||
# Substrate Collectables Workshop: Starting Template | ||
|
||
Our starting template for this tutorial uses the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk). | ||
This is the starting template for: https://github.com/shawntabrizi/substrate-collectables-workshop | ||
|
||
This is the same technology stack used to build and power the [Polkadot Network](https://polkadot.network/). | ||
## Setup | ||
|
||
To better understand what you will be doing in this tutorial, we need to start with a high level overview of blockchains. | ||
Follow [these installation instructions](https://docs.substrate.io/install/) to set up your development environment to work with the `polkadot-sdk`. | ||
|
||
## Blockchain | ||
### test | ||
|
||
Blockchains are the foundation of building Web3 technologies. | ||
To check that your code compiles successfully at each step, you can run: | ||
|
||
Web3 is a promise toward a world with less trust, and more truth. | ||
```bash | ||
cargo test | ||
``` | ||
|
||
Through blockchain technology, we are able to develop and deploy software that are decentralized, open, permissionless, censorship resistant, and independently verifiable. | ||
You should run this now to make sure this starting template is compiling successfully for you. | ||
|
||
The main purpose of a blockchain node is to come to consensus with other nodes on the decentralized network. | ||
At the beginning and end of every step, you should be able to run `cargo test` without warning or errors. If you have either, you should learn from them and fix them! | ||
|
||
<details> | ||
### rustfmt | ||
|
||
<summary>Deep Dive</summary> | ||
To keep your code clean and easy to read, we use a tool called [`rustfmt`](https://github.com/rust-lang/rustfmt). To access all the latest features of `rustfmt` we specifically use the `nightly` toolchain. | ||
|
||
If you want to learn more about blockchains, check out the following video from the Polkadot Blockchain Academy: | ||
To install `rustfmt` for `nightly`: | ||
|
||
<iframe width="560" height="315" src="https://www.youtube.com/embed/8UvdfFGYFiE?si=5PIyppVBZ91vUtjf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> | ||
```bash | ||
rustup component add rustfmt --toolchain nightly | ||
``` | ||
|
||
</details> | ||
To configure the behavior of `rustfmt`, we have included a `rustfmt.toml` file. | ||
|
||
## Runtime | ||
Try running: | ||
|
||
At the heart of a blockchain is a [state transition function](https://en.wikipedia.org/wiki/Finite-state_machine) (STF). | ||
```bash | ||
cargo +nightly fmt | ||
``` | ||
|
||
This is the logic of the blockchain, and defines all the ways a blockchain is allowed to manipulate the blockchain state. | ||
You shouldn't see any changes this time around, but as you write more code, you will be able to see `cargo +nightly fmt` make everything look pretty, consistent, and easy to read. | ||
|
||
In the `polkadot-sdk` we refer to this logic as the blockchain's runtime. | ||
> We recommend you run `cargo +nightly fmt` after every step! | ||
All nodes on a blockchain network have and use the same runtime, allowing them to come to consensus about changes to a blockchain. | ||
### clippy | ||
|
||
<details> | ||
[Clippy](https://github.com/rust-lang/rust-clippy) is a collection of lints to catch common mistakes and improve your Rust code. We also use the `nightly` toolchain here to gain access to the latest features. | ||
|
||
<summary>Deep Dive</summary> | ||
To install `clippy` for `nightly`: | ||
|
||
To learn more about the runtime, and its role inside of the `polkadot-sdk`, check out this video from the Polkadot Blockchain Academy: | ||
```bash | ||
rustup component add clippy | ||
``` | ||
|
||
<iframe width="560" height="315" src="https://www.youtube.com/embed/-ttmm8gYS04?si=ZH_g83CVtguENoK7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> | ||
Try running: | ||
|
||
</details> | ||
```bash | ||
cargo +nightly clippy | ||
``` | ||
|
||
## FRAME | ||
Again, you shouldn't see any errors here, but as you write code for this tutorial, `clippy` can be used to help improve the quality of your code. | ||
|
||
The `polkadot-sdk` provides a developer framework called FRAME. | ||
## Cheat Sheet | ||
|
||
FRAME is an opinionated framework on how one should quickly and easily build and maintain a blockchain's runtime. | ||
You should run these 3 commands at the end of every step without any errors or warnings. | ||
|
||
> NOTE: It is important to clarify that FRAME is not the only way you can develop a runtime for the `polkadot-sdk`, but it is the one that the Polkadot Network uses and is most supported by the ecosystem. | ||
You can see in our project, nearly all of our dependencies come from a single crate named [`frame`](https://docs.rs/polkadot-sdk-frame/0.6.0/polkadot_sdk_frame/index.html). | ||
|
||
This crate is really just a convenience wrapper around other smaller crates, all exposed through [`frame::deps`](https://docs.rs/polkadot-sdk-frame/0.6.0/polkadot_sdk_frame/deps/index.html). | ||
|
||
For our tutorial, most of the types and traits we need access to are automatically brought into scope through [`frame::prelude::*`](https://docs.rs/polkadot-sdk-frame/0.6.0/polkadot_sdk_frame/prelude/index.html), however once in a while, we will need to import something more specific from [`frame::primitives`](https://docs.rs/polkadot-sdk-frame/0.6.0/polkadot_sdk_frame/primitives/index.html) or [`frame::traits`](https://docs.rs/polkadot-sdk-frame/0.6.0/polkadot_sdk_frame/traits/index.html). | ||
|
||
### Pallets | ||
|
||
FRAME's key decision is to break apart the blockchain runtime into separate logical pieces that can choose to interact with one another. | ||
|
||
These logical pieces are called Pallets. | ||
|
||
TODO: Add images. | ||
|
||
You can think of different Pallets as different applications or functions that your blockchain exposes. | ||
|
||
You can also think of Pallets very similar to traditional blockchain smart contracts, however Pallets are more powerful and execute much faster than smart contracts. | ||
|
||
<details> | ||
|
||
<summary>Deep Dive</summary> | ||
|
||
To learn more about FRAME and Pallets, check out this video from the Polkadot Blockchain Academy: | ||
|
||
<iframe width="560" height="315" src="https://www.youtube.com/embed/ghMloMzEEsA?si=3DtsmrYOapbnR2oy" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> | ||
|
||
</details> | ||
|
||
## NFTs | ||
|
||
Non-Fungible Tokens (NFTs) are a type of token which can be created and traded on a blockchain. | ||
|
||
As their name indicated, each NFT is totally unique, and therefore non-fungible with one another. | ||
|
||
NFTs can be used for many things, for example: | ||
|
||
- Representing real world assets | ||
- Ownership Rights | ||
- Access Rights | ||
- Digital assets | ||
- Music | ||
- Images | ||
- Skins | ||
- Characters | ||
- and much more... | ||
|
||
## Starting Template | ||
|
||
The template for this project is a minimal starting point for developing a custom Pallet. | ||
|
||
In this tutorial, we will create a Pallet which allows us to create and manage a collection of NFTs. | ||
|
||
Our NFTs will represent kitties, which will be a digital pet that can be created, traded, and more. | ||
|
||
This Pallet could then be included into a `polkadot-sdk` project and used to launch a Web3 application on the Polkadot Network. | ||
|
||
TODO: need to create and link to a tutorial creating and launching a runtime with omninode. | ||
```bash | ||
cargo +nightly fmt | ||
cargo +nightly clippy | ||
cargo test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
{ | ||
"_Note": "This file will not be included in your final gitorial.", | ||
"commitMessage": "action: learn about the polkadot sdk" | ||
"commitMessage": "starting-template" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.