Skip to content
/ dots Public

Demonstrational & educational project to showcase interactions with Substrate- and FRAME-based blockchains

Notifications You must be signed in to change notification settings

danforbes/dots

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dots

The purpose of this project is to elucidate the details of interacting with Substrate- and FRAME-based blockchains via front-end JavaScript and WebAssembly (Wasm). The code in this repository is for educational and demonstrational purposes only - it is not intended for production. This project demonstrates the following capabilities:

Those who are familiar with the above concepts may wish to skip ahead to the Usage section.

Background

Substrate is a Rust framework for building blockchains; FRAME is Substrate's framework for building blockchain runtimes. A "runtime" is the component of a blockchain system that represents end-user, application capabilities. Blockchains that are built with Substrate and FRAME are self-describing systems that expose metadata, which enables the dynamic, programmatic creation of interfaces that allow users to interact with the blockchain runtime.

Project Components

The following sections give a brief overview of the components of this project.

SCALE Codec

SCALE is Substrate's lightweight and efficient codec (i.e. data serialization algorithm). The SCALE encoding omits contextual information in pursuit of efficiency, which means that in order to decode SCALE data, it's necessary to independently posses a type registry that defines the structures/schemas of the objects in the data that is to be decoded. Further details of the SCALE codec are outlined in a separate document. Although it may have been possible to reuse existing Rust code and compile it to Wasm, fighting the Rust type system proved too challenging for an initial implementation - this is potentially an opportunity to improve this project. For now, this project uses a simple JavaScript SCALE implementation.

FRAME Metadata

The metadata exposed by FRAME runtimes consists of three components: 1) a type registry to enable the SCALE-encoding and -decoding of messages to and from the runtime, 2) a list that describes the data that must be included with signed extrinsics, and 3) an exhaustive description of the runtime's public interface. Since Substrate and FRAME are Rust-based frameworks, the metadata that is exposed by FRAME runtimes is defined as a Rust struct, in particular the frame_metadata::v14::RuntimeMetadataV14 type has been used by FRAME since around the end of 2021. When a user requests the metadata from a FRAME-based runtime, the runtime returns a hexadecimal string that represents the SCALE-encoding of its frame_metadata::v14::RuntimeMetadataV14 instance. Although it would be possible to decode the hex string and parse the metadata in JavaScript (as in this older code that does so for version 11 of FRAME metadata), doing so in Rust and making the resulting code available as Wasm has two primary benefits: 1) it relies on existing, unit- and battle-tested libraries that are provided by the maintainers of Substrate, 2) it allows for reliable, efficient transformation of the metadata into a structure that is better suited for front-end/client-side use. The Rust code that decodes and transforms the metadata can be found in rs/metadata/src/lib.rs. Further details about the frame_metadata::v14::RuntimeMetadataV14 format and the transformations that are applied to it are documented in a separate file.

Accounts

Like the decoding and transformation of metadata, most of this project's account capabilities are implemented in Rust and made available to the front-end as Wasm. The code, which is located in the rs/account/src/lib.rs file, was more or less copied directly from Polkadot-JS and is fairly self-explanatory. This project supports importing an existing, known account from its 32-byte sr25519 private seed, or generating a new BIP39 seed phrase and using that to derive an sr25519 keypair. An sr25519 account can be used to sign a message, and a 32-byte sr25519 public key and an Ss58 network identifier can be used to derive an Ss58 address for that account.

JSON-RPC

Substrate uses a JSON-RPC server as its primary mechanism for interacting with end-users. This project defines a JavaScript class named Context as an abstraction on top of a WebSocket connection to a Substrate node's JSON-RPC server. Substrate implements a specification called PSP-6 in order to define its JSON-RPC interface; this project relies on a small subset of the endpoints defined by this specification. The Context class, which can be found in the lib/context.js file, makes use of the following PSP-6 endpoints:

Signed Extrinsics

The term "extrinsic" is native to Substrate and is used to refer to any external data that is included in a block of a blockchain. The most straightforward usage of this term applies to "signed extrinsics", which are colloquially referred to as "transactions". Signed extrinsics allow blockchain end-users to interact with the blockchain runtime; as the name implies, requests of this type must be signed by the private key that is associated with a blockchain account, which allows the blockchain network to debit that user's account in order to pay the fees associated with that request. Other types of extrinsics, like unsigned extrinsics or inherents, are out of the scope of this project at this time. Extrinsic encoding is implemented in the submitExtrinsic method of the Context class. More details about the encoding of signed extrinsics are documented in a separate file.

Usage

This project includes a simple browser front-end that is built with standard Web Components. The front-end uses the metadata from a Substrate- and FRAME-based blockchain to enumerate the modules ("pallets") that inform the blockchain runtime. Pallets may expose storage items or dispatchable calls, and the front-end can be used to query storage items and submit dispatchable calls in the form of signed extrinsics.

Requirements

Other than a browser and an HTTP server, the only requirement for building and using this project is wasm-pack and its associated dependencies for building the Wasm libraries. First, install Rust, then install wasm-pack. This project includes a package.json file that provides a command for launching a simple HTTP server, which requires Node.js.

Installation

To build the Wasm libraries and their bindings, and install them in the expected directory (lib/wasm), execute the build:wasm NPM script:

npm run build:wasm

Web UI

Launch the web UI by executing the start NPM script:

npm start

About

Demonstrational & educational project to showcase interactions with Substrate- and FRAME-based blockchains

Topics

Resources

Stars

Watchers

Forks