Exploring Substrate
Tags: substrate, rust, web3
Published: 2021-09-05 17:48:54

Hi there! welcome back, this will be the first post of a new  serie exploring the [Substrate](https://substrate.dev/) framework. We will be using the [tutorials](https://substrate.dev/en/tutorials) and [recipes](https://substrate.dev/recipes/) from the Substrate Developer Hub as our road map to exploring and learning.

As the landing page of the hub says, `Substrate is a modular framework that enables you to create purpose-built blockchains by composing custom or pre-built components.`, that means that you can create your first Substrate Chain by using the pre-built components that the framework offer. And that is what the [first tutorial](https://substrate.dev/docs/en/tutorials/create-your-first-substrate-chain/) is about.

You can follow the first tutorial for detailed instructions, but make sure to review the [installation page](https://substrate.dev/docs/en/knowledgebase/getting-started/) for setup your environment.

Let's continue with the exploration, assuming that you already cloned the needed `templates`, first we need to build the `node` (**in release mode**).

```bash
# node
$ cargo build --release
```

And then you can run both `front-end and node` in different terminals

First the `node` using the `--dev` and `--tmp` flags

```bash
$ ./target/release/node-template --dev --tmp

2021-09-03 19:39:37 Running in --dev mode, RPC CORS has been disabled.
2021-09-03 19:39:37 Substrate Node
2021-09-03 19:39:37 ✌️  version 3.0.0-monthly-2021-08-cd936fc-x86_64-macos
2021-09-03 19:39:37 ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2021
2021-09-03 19:39:37 📋 Chain specification: Development
2021-09-03 19:39:37 🏷 Node name: efficacious-cart-4351
```

And the front-end

```bash
# front-end
yarn i
yarn start
...
You can now view substrate-front-end-template in the browser.

  Local:            http://localhost:8000/substrate-front-end-template
  On Your Network:  http://192.168.0.175:8000/substrate-front-end-template

```

You will get a nice UI that allow you to interact with your first Substrate Chain :) 

![Substrate UI ](https://user-images.githubusercontent.com/363911/132093206-008a0320-826d-43f5-814a-d7dde215d594.png)


And even you can interact and make transfers between the test accounts :)

![Transfer UI image](https://user-images.githubusercontent.com/363911/132093527-6de26d33-98bc-4f29-ac73-d5a76fe63eeb.png)

Great!! we complete the first tutorial, we can also explore other options un the UI and interact with our first chain :)

---

Let's now continue, we will first add add the `nicks` `pallet` following the [next tutorial](https://substrate.dev/docs/en/tutorials/add-a-pallet/). But first a little definition from the [KB page](https://substrate.dev/docs/en/knowledgebase/runtime/pallets):

> Pallets are a special kind of Rust module made up of a set of types, trait implementations and functions from which Substrate runtimes can be composed. FRAME not only provides a library of commonly used Substrate pallets but also a framework to build custom domain-specific pallets, giving runtime engineers the flexibility to define their runtime's behaviour according to their target use case. The result: each pallet has its own discrete logic which can modify the features and functionality of your blockchain's state transition functions.


You can follow the detailed explanation in the tutorial, but in a nutshell to add the `pallet` you need to modify two files. First you need to add the `dep` to the `runtime` crate.

```toml
// runtime/Cargo.toml
(...)
[dependencies.pallet-nicks]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
tag = 'monthly-2021-08'
version = '4.0.0-dev'
```
*Note:* The `version` and `tag` may be outdate, you can check the latest ones.

And also we need to add the `feature` to the `std` features of the `runtime` crate ( you can read in the [tutorial](https://substrate.dev/docs/en/tutorials/add-a-pallet/import-a-pallet#crate-features) for a nice explanation)

```toml
// runtime/Cargo.toml
std = [
(...)
    'pallet-balances/std',
    'pallet-nicks/std',
(...)
```

Great! Now is time to `configure` the `pallet`, since every `pallet` needs to implement the `Config` trait in order to be  included in the runtime (by the `construct_runtime` macro).

We can here use the `help` of the [rust-analyzer](https://rust-analyzer.github.io/) to get the skeleton of the needed members.

```rust
// runtime/src/lib.rs
impl pallet_nicks::Config for Runtime {
    type Event;

    type Currency;

    type ReservationFee;

    type Slashed;

    type ForceOrigin;

    type MinLength;

    type MaxLength;
}
```

And, also detailed in the tutorial, we had another macro (`parameter_types`) to help us defined constant values. Let use this macro to define some constants needed in the configuration.

```rust
// runtime/src/lib.rs
parameter_types! {
	pub const NickReservationFee: u128 = 100;
	pub const MinNickLength: usize = 8;
	pub const MaxNickLength: usize = 16;
}
```

And now let go to the trait implementation block and complete the needed config (using the code from the tutorial).

```rust
// runtime/src/lib.rs
    // The Balances pallet implements the ReservableCurrency trait.
    // `Balances` is defined in `construct_runtimes!` macro. See below.
    // https://substrate.dev/rustdocs/latest/pallet_balances/index.html#implementations-2
    type Currency = Balances;

    // Use the NickReservationFee from the parameter_types block.
    type ReservationFee = NickReservationFee;

    // No action is taken when deposits are forfeited.
    type Slashed = ();

    // Configure the FRAME System Root origin as the Nick pallet admin.
    // https://substrate.dev/rustdocs/latest/frame_system/enum.RawOrigin.html#variant.Root
    type ForceOrigin = frame_system::EnsureRoot<AccountId>;

    // Use the MinNickLength from the parameter_types block.
    type MinLength = MinNickLength;

    // Use the MaxNickLength from the parameter_types block.
    type MaxLength = MaxNickLength;

    // The ubiquitous event type.
    type Event = Event;
```

Last, we need to add the `pallet` to the `runtime` by adding to the `construct_runtime` macro call.

```rust
// runtime/src/lib.rs
construct_runtime!(
	pub enum Runtime where
		Block = Block,
		NodeBlock = opaque::Block,
		UncheckedExtrinsic = UncheckedExtrinsic
	{
		System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
		RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage},
		Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
		Aura: pallet_aura::{Pallet, Config<T>},
		Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event},
		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
		TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
		Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>},
		// Include the custom logic from the pallet-template in the runtime.
		TemplateModule: pallet_template::{Pallet, Call, Storage, Event<T>},
		// add nicks pallet
		Nicks: pallet_nicks::{Pallet, Call, Storage, Event<T>},
	}
);
```

Awesome! Time to compile again and see it in action :)

```bash
$ cargo build --release
```

And we get an error, the trait `From<usize>` is not implemented for `u32`.
![error compiling](https://user-images.githubusercontent.com/363911/132124517-d147f6df-fe13-447a-bdf5-4bbb82c2c25c.png)

We can look at the [Get trait](https://github.com/paritytech/substrate/blob/master/frame/support/src/traits/misc.rs#L38-L73) in the substrate repo for more details in the implementation, but for now let go to our code and change the `usize` to `u32`. *Update: there is already a PR in the tutorial repo to fix this and use u32.*


```rust

// runtime/src/lib.rs
parameter_types! {
	pub const NickReservationFee: u128 = 100;
	pub const MinNickLength: u32 = 8;
	pub const MaxNickLength: u32 = 16;
}
```

Let try to compile again...

```bash
$ cargo build --release
(...)
Finished release [optimized] target(s) in 18m 57s
```

Nice! we can run again and interact with the `nicks` pallet.

```bash
$ ./target/release/node-template --dev --tmp
```
Set the nick of Alice address

![set nick](https://user-images.githubusercontent.com/363911/132125445-54440f7e-6f35-4f49-9c21-4b3c81caa8bf.png)

Wait, looking at the `Events` there is an error in the execution

```
system:ExtrinsicFailed:: (phase={"applyExtrinsic":1})-2
DispatchError: {"module":{"index":9,"error":1}}, DispatchInfo: {"weight":50000000,"class":"Normal","paysFee":"Yes"}
An extrinsic failed. \[error, info\]
```

After looking how to read this errors I found a nice explanation in this [so answer](https://stackoverflow.com/a/67769831/587894)

> For future occasions there it goes a tip when a dispatch error happens. index:9 and error:0 are the index of the pallet in construct_runtime! which is throwing the error, and the index of the error in the #[pallet::error] definition of the pallet concerned.

So, in our case `index:9` is the `nicks` pallet and we `error:1` is `TooLong` (defined in this [line](https://github.com/paritytech/substrate/blob/master/frame/nicks/src/lib.rs#L114)), since remember we set the `MaxNickLength` to **16**. Let's try with a `nick` with an accepted length(between 8 and 16).

![image](https://user-images.githubusercontent.com/363911/132129054-39449393-dd77-4027-b6e1-c1f7aa0a1c9f.png)

Nice! works as expected! We can also check by `query`ing the `nameOf` using the address of Alice.

![image](https://user-images.githubusercontent.com/363911/132129163-64528619-e7f7-42c1-94e5-fb0ebc5814f1.png)

Great! we get the Alice's`nick` (hex-encoded) and amount used for reserve the nick.

---

That's all for today, we followed the first two tutorials of the 
[Substrate Developer Hub](https://substrate.dev/) and make our first interactions with the framework :)

As always, I write this as a learning journal and any feedback is welcome 🙌. In the next post I will try to write a simple `pallet` and integrate with our current chain, stay tune 😃

Thanks!