Skip to content

Commit

Permalink
Merge branch 'main' into eshaben/add-termynal
Browse files Browse the repository at this point in the history
  • Loading branch information
eshaben authored Jan 16, 2024
2 parents ebc0a9c + b7a10f7 commit 2881ea6
Show file tree
Hide file tree
Showing 130 changed files with 393 additions and 380 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ Next, you will create the script for this file and complete the following steps:
5. Extract the compiled contract file and export it to be used in the deployment script

```js
--8<-- 'code/ethereum-api/compile.js'
--8<-- 'code/builders/interact/ethereum-api/compile.js'
```
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ touch Incrementer.sol
Next, you can add the Solidity code to the file:

```solidity
--8<-- 'code/ethereum-api/Incrementer.sol'
--8<-- 'code/builders/interact/ethereum-api/Incrementer.sol'
```

The `constructor` function, which runs when the contract is deployed, sets the initial value of the number variable stored on-chain (default is 0). The `increment` function adds the `_value` provided to the current number, but a transaction needs to be sent, which modifies the stored data. Lastly, the `reset` function resets the stored value to zero.
Expand Down
1 change: 0 additions & 1 deletion .snippets/text/example.md

This file was deleted.

20 changes: 10 additions & 10 deletions builders/build/customize/adding-built-in-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ description: Substrate is a modular blockchain framework that includes many read

Substrate is a powerful and modular software development framework included in the Polkadot SDKs for building blockchains. It provides a comprehensive set of tools and libraries that abstract complex blockchain functionalities, allowing developers to focus on building innovative features and applications by focusing on the runtime, which contains the core logic and the rules of the state transition for the use case.

What sets Substrate apart is its modular architecture, which enables the seamless integration of [built-in modules](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame){target=_blank} and the creation of custom ones, facilitating the development of blockchain protocols.
What sets Substrate apart is its modular architecture, which enables the seamless integration of [built-in modules](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame){target=\_blank} and the creation of custom ones, facilitating the development of blockchain protocols.

For cases requiring only EVM (Ethereum Virtual Machine) compatibility, the template provided in the [Tanssi repository](https://github.com/moondance-labs/tanssi#container-chain-templates){target=_blank} fulfills the requirements without further modifications. However, teams aiming to build a Substrate Appchain must add and configure both built-in and custom modules within the runtime. This involves compiling, generating the chain specification, and deploying through the Tanssi protocol to transform it into a live ContainerChain.
For cases requiring only EVM (Ethereum Virtual Machine) compatibility, the template provided in the [Tanssi repository](https://github.com/moondance-labs/tanssi#container-chain-templates){target=\_blank} fulfills the requirements without further modifications. However, teams aiming to build a Substrate Appchain must add and configure both built-in and custom modules within the runtime. This involves compiling, generating the chain specification, and deploying through the Tanssi protocol to transform it into a live ContainerChain.

This article focuses on the necessary steps for adding a built-in module to the EVM template.

Expand All @@ -20,9 +20,9 @@ This article focuses on the necessary steps for adding a built-in module to the
To follow the steps in this guide, you will need to have the following:

- A healthy development environment with the Rust compiler and Cargo package manager
- The [Tanssi repository](https://github.com/moondance-labs/tanssi){target=_blank}, cloned from GitHub
- The [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank}, cloned from GitHub

You can read more about how to install the required components in the [prerequisites article](/builders/build/customize/prerequisites){target=_blank}.
You can read more about how to install the required components in the [prerequisites article](/builders/build/customize/prerequisites){target=\_blank}.

As this article is based on the EVM template, make sure that it compiles correctly before continuing by executing the following command:

Expand All @@ -38,13 +38,13 @@ Modules are meant to provide the functionality needed in very different use case

To add a module, the following steps are necessary:

1. Make the dependency available within the project by declaring it in [Cargo](https://doc.rust-lang.org/cargo/){target=_blank}, the Rust language package manager
1. Make the dependency available within the project by declaring it in [Cargo](https://doc.rust-lang.org/cargo/){target=\_blank}, the Rust language package manager
2. Make the standard (`std`) features of the module available to the compiler
3. Configure the module
4. Add the module to the runtime
5. Add the default configuration to the chain specification

In the following example, the popular Substrate module `pallet-assets` is added to the runtime of the provided EVM template, found in the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=_blank}, specifically in the folder `container-chains/templates/frontier/`.
In the following example, the popular Substrate module `pallet-assets` is added to the runtime of the provided EVM template, found in the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank}, specifically in the folder `container-chains/templates/frontier/`.

### Declare the Dependency {: #declare-dependency }

Expand Down Expand Up @@ -98,7 +98,7 @@ The configuration of new modules requires implementing a configuration `trait` f
impl pallet_assets::Config for Runtime { ... }
```

[Traits](https://doc.rust-lang.org/book/ch10-02-traits.html){target=_blank} are a way of defining shared behavior in Rust, and in this case, they allow a new runtime to benefit from the functionality the Assets module provides only by implementing its configuration trait and parameters.
[Traits](https://doc.rust-lang.org/book/ch10-02-traits.html){target=\_blank} are a way of defining shared behavior in Rust, and in this case, they allow a new runtime to benefit from the functionality the Assets module provides only by implementing its configuration trait and parameters.

Some of the parameters the trait needs to define might be constant values, in which case, they have to be defined and enclosed within the macro `parameter_types!`, which helps us to reduce the development effort by expanding the code and converting each of the constants into the correct struct type with functions that allow the runtime to read its type and values in a standardized way.

Expand Down Expand Up @@ -153,10 +153,10 @@ impl pallet_assets::Config for Runtime {
??? code "View the complete script"

```rust
--8<-- 'code/basic-substrate/built-in-pallet-configuration.rs'
--8<-- 'code/builders/build/customize/built-in-module/built-in-pallet-configuration.rs'
```

The complete configuration of the module contains more parameters, to view a detailed description of each of them, refer to the [official config trait for the Assets module documentation](https://paritytech.github.io/substrate/master/pallet_assets/pallet/trait.Config.html){target=_blank}.
The complete configuration of the module contains more parameters, to view a detailed description of each of them, refer to the [official config trait for the Assets module documentation](https://paritytech.github.io/substrate/master/pallet_assets/pallet/trait.Config.html){target=\_blank}.

### Add the Module to the Runtime {: #add-module-to-runtime }

Expand Down Expand Up @@ -194,7 +194,7 @@ container-chains/templates/frontier/node/src/chain_spec.rs

The function `testnet_genesis`, presented in the following code snippet, defines the initial state for the modules included in the runtime (such as initial funded accounts, for example). After adding the Assets module, it is necessary to initialize it as well, and in the following example, its default values are defined.

More about the chain specification and how to configure it will be covered in the article [Customizing Chain Specifications](/builders/build/customize/customizing-chain-specs/){target=_blank}.
More about the chain specification and how to configure it will be covered in the article [Customizing Chain Specifications](/builders/build/customize/customizing-chain-specs/){target=\_blank}.

```rust hl_lines="14"
fn testnet_genesis(
Expand Down
33 changes: 17 additions & 16 deletions builders/build/customize/adding-custom-made-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: Substrate is a modular blockchain framework that makes it easy to b

By providing a comprehensive library of pre-built modules addressing many common requirements, the framework greatly simplifies the process of building an Appchain and accelerates the deployment and evolution into a ContainerChain. However, addressing an innovative use case usually requires a development effort to fully meet the requirements, and, in Substrate, adding custom logic translates into writing and integrating runtime modules.

The example presented in the [Modularity](/learn/framework/modules/#custom-module-example){target=_blank} article shows a simple lottery module exposing two transactions:
The example presented in the [Modularity](/learn/framework/modules/#custom-module-example){target=\_blank} article shows a simple lottery module exposing two transactions:

- **Buy tickets** - this function manages a user's entry into the lottery. In essence, it verifies that the participant has a sufficient balance, is not already participating, and takes care of transferring funds to register the user for the lottery
- **Award prize** - this function that handles a user entering into the lottery. At a high level, it fetches a pseudo random number to obtain a winner and handles the award distribution
Expand All @@ -23,22 +23,22 @@ In this article, the following steps, necessary to build and add the example mod
3. Adding custom logic
4. Configure the runtime with the new module

--8<-- 'text/common/not-for-production-code-guard.md'
--8<-- 'text/_common/not-for-production-code-guard.md'

## Checking Prerequisites {: #checking-prerequisites }

To follow the steps in this guide, you will need to have the following:

- Clone the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=_blank} from Github
- Clone the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank} from Github
- Rust compiler and Cargo package manager

You can read more about how to install Rust and Cargo is in the [prerequisites article](/builders/build/customize/prerequisites/#installing-rust){target=_blank}.
You can read more about how to install Rust and Cargo is in the [prerequisites article](/builders/build/customize/prerequisites/#installing-rust){target=\_blank}.

## Creating the Lottery Module Files {: #creating-lottery-module-files }

Before starting your coding process, it's essential to create the files containing your logic. Substrate modules are abstract and intended for reuse across different runtimes with various customizations. To achieve this, you'll use Cargo, Rust's package manager, to create the module as a new package.

As mentioned in the prerequisites section, the first step is to clone the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=_blank} and, from the root folder, navigate to `pallets`, where the module will be created.
As mentioned in the prerequisites section, the first step is to clone the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank} and, from the root folder, navigate to `pallets`, where the module will be created.

```bash
cd container-chains/pallets
Expand Down Expand Up @@ -81,14 +81,14 @@ The full example of the `Cargo.toml` file sets, besides the attributes, the depe
??? code "View the complete Cargo.toml file"

```rust
--8<-- 'code/basic-substrate/lottery-example-cargo.toml'
--8<-- 'code/builders/build/customize/custom-made-module/lottery-example-cargo.toml'
```

## Adding Custom Logic {: #adding-custom-logic}

As presented in the [custom-made module](/learn/framework/modules/#custom-modules){target=_blank} section of the modularity article, creating a module involves implementing the following attribute macros, of which the first three are mandatory:
As presented in the [custom-made module](/learn/framework/modules/#custom-modules){target=\_blank} section of the modularity article, creating a module involves implementing the following attribute macros, of which the first three are mandatory:

--8<-- 'text/substrate/pallets-macros-descriptions.md'
--8<-- 'text/builders/build/customize/custom-made-module/pallets-macros-descriptions.md'

### Implementing the Module Basic Structure {: #implementing-basic-structure }

Expand All @@ -113,7 +113,7 @@ The next step would be to add the third mandatory macro (`#[pallet::config]`) an

To make the modules highly adaptable, their configuration is abstract enough to allow them to be adapted to the specific requirements of the use case the runtime implements.

The implementation of the `#[pallet::config]` macro is mandatory and sets the module's dependency on other modules and the types and values specified by the runtime-specific settings. More about module dependencies is in the [Substrate documentation](https://docs.substrate.io/build/pallet-coupling/){target=_blank}.
The implementation of the `#[pallet::config]` macro is mandatory and sets the module's dependency on other modules and the types and values specified by the runtime-specific settings. More about module dependencies is in the [Substrate documentation](https://docs.substrate.io/build/pallet-coupling/){target=\_blank}.

In the custom `lottery-example` module you are building, the module depends on other modules to manage the currency and the random function to select the winner. The module also reads and uses the ticket price and the maximum number of participants directly from the runtime settings. Consequently, the configuration needs to include these dependencies:

Expand Down Expand Up @@ -163,7 +163,7 @@ Calls represent the behavior a runtime exposes in the form of transactions that
Every call is enclosed within the `#[pallet::call]` macro, and present the following elements:

- **Call Index** - is a mandatory unique identifier for every dispatchable call
- **Weight** - is a measure of computational effort an extrinsic takes when being processed. More about weights is in the [Substrate documentation](https://docs.substrate.io/build/tx-weights-fees/){target=_blank}
- **Weight** - is a measure of computational effort an extrinsic takes when being processed. More about weights is in the [Substrate documentation](https://docs.substrate.io/build/tx-weights-fees/){target=\_blank}
- **Origin** - identifies the signing account making the call
- **Result** - the return value of the call, which might be an `Error` if anything goes wrong

Expand Down Expand Up @@ -225,7 +225,7 @@ Here is the complete implementation of the calls with the custom lottery logic:
??? code "View the complete calls code"

```rust
--8<-- 'code/basic-substrate/lottery-example-calls.rs'
--8<-- 'code/builders/build/customize/custom-made-module/lottery-example-calls.rs'
```

### Implementing Custom Errors {: #implementing-custom-errors}
Expand Down Expand Up @@ -265,9 +265,9 @@ pub enum Event<T: Config> {

### Implementing Storage for State Persistence {: #implementing-storage }

The `#[pallet::storage]` macro initializes a runtime storage structure. In the heavily constrained environment of an Appchain, deciding what to store and which structure to use can be critical in terms of performance. More on this topic is covered in the [Substrate documentation](https://docs.substrate.io/build/runtime-storage/){target=_blank}.
The `#[pallet::storage]` macro initializes a runtime storage structure. In the heavily constrained environment of an Appchain, deciding what to store and which structure to use can be critical in terms of performance. More on this topic is covered in the [Substrate documentation](https://docs.substrate.io/build/runtime-storage/){target=\_blank}.

In this example, the `lottery-example` module needs a basic value storage structure to persist the list of participants in a bounded capacity vector ([BoundedVec](https://crates.parity.io/frame_support/storage/bounded_vec/struct.BoundedVec.html){target=_blank}). This can be initialized as follows:
In this example, the `lottery-example` module needs a basic value storage structure to persist the list of participants in a bounded capacity vector ([BoundedVec](https://crates.parity.io/frame_support/storage/bounded_vec/struct.BoundedVec.html){target=\_blank}). This can be initialized as follows:

```rust
#[pallet::storage]
Expand All @@ -278,19 +278,20 @@ pub(super) type Participants<T: Config> = StorageValue<
OptionQuery
>;
```

### The Complete Module {: #complete-module }

To put all the pieces together, after implementing all the required macros and adding the custom logic, the module is now complete and ready to be used in the runtime.

??? code "View the complete module file"

```rust
--8<-- 'code/modules/lottery-example.rs'
--8<-- 'code/builders/build/customize/custom-made-module/lottery-example.rs'
```

## Configure the Runtime {: #configure-runtime }

Finally, with the module finished, it can be included in the runtime. By doing so, the transactions `buy_tickets` and `award_prize` will be callable by the users. This also means that the [Polkadot.js API](/builders/interact/substrate-api/polkadot-js-api/){target=_blank} will be decorated with this module and all the available calls that it contains.
Finally, with the module finished, it can be included in the runtime. By doing so, the transactions `buy_tickets` and `award_prize` will be callable by the users. This also means that the [Polkadot.js API](/builders/interact/substrate-api/polkadot-js-api/){target=\_blank} will be decorated with this module and all the available calls that it contains.

To configure the runtime, open the `lib.rs` file, which contains the definition for the runtime of the included template and is located (in case of using the EVM-compatible) in the folder:

Expand Down Expand Up @@ -338,4 +339,4 @@ construct_runtime!(

With everything set, the Appchain now has support for a basic implementation of a lottery.

--8<-- 'text/disclaimers/third-party-content.md'
--8<-- 'text/_disclaimers/third-party-content.md'
Loading

0 comments on commit 2881ea6

Please sign in to comment.