Chopsticks by Acala

Introduction

Chopsticks provides a developer-friendly method of locally forking existing Substrate based chains. It allows for the replaying of blocks to easily examine how extrinsics effect state, the forking of multiple blocks for XCM testing, and more. This allows developers to test and experiment with their own custom blockchain configurations in a local development environment, without the need to deploy a live network.

Overall, Chopsticks aims to simplify the process of building blockchain applications on Substrate and make it accessible to a wider range of developers.

Forking Phron with Chopsticks

To use Chopsticks, you can install it as a package with the Node package manager or Yarn:

npm i @acala-network/chopsticks@latest

Once installed, you can run commands with the Node package executor. For example, this runs Chopstick's base command:

npx @acala-network/chopsticks@latest

To run Chopsticks, you will need some sort of configuration, typically through a file. Chopsticks' source repository includes a set of YAML configuration files that can be used to create a local copy of a variety of Substrate chains. You can download the configuration files from the source repository's configs folder.

Phron all have default files available:

endpoint: wss://testnet.phron.ai
mock-signature-host: true
db: ./db.sqlite

import-storage:
  System:
    Account:
      -
        -
          - "0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"
        - data:
            free: "100000000000000000000000"
  TechCommitteeCollective:
    Members: ["0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"]
  CouncilCollective:
    Members: ["0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"]
  TreasuryCouncilCollective:
    Members: ["0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"]
  AuthorFilter:
    EligibleRatio: 100
    EligibleCount: 100

These are the settings that can be included in the config file:

OptionDescription

genesis

The link to a parachain's raw genesis file to build the fork from, instead of an endpoint.

timestamp

Timestamp of the block to fork from.

endpoint

The endpoint of the parachain to fork.

block

Use to specify at which block hash or number to replay the fork.

wasm-override

Path of the WASM to use as the parachain runtime, instead of an endpoint's runtime.

db

Path to the name of the file that stores or will store the parachain's database.

config

Path or URL of the config file.

port

The port to expose an endpoint on.

build-block-mode

How blocks should be built in the fork: batch, manual, instant.

import-storage

A pre-defined JSON/YAML storage file path to override in the parachain's storage.

allow-unresolved-imports

Whether to allow WASM unresolved imports when using a WASM to build the parachain.

html

Include to generate storage diff preview between blocks.

mock-signature-host

Mock signature host so that any signature starts with 0xdeadbeef and filled by 0xcd is considered valid.

You can use the configuration file with the base command npx @acala-network/chopsticks@latest to fork assets by providing it with the --config flag.

You can use a raw GitHub URL of the default configuration files, a path to a local configuration file, or simply use the chain's name for the --config flag. For example, the following commands all use Phron's configuration in the same way:

npx @acala-network/chopsticks@latest --config=phron

Note!

If using a file path, make sure you've downloaded the Phron configuration file, or have created your own.

A configuration file is not necessary, however. All of the settings (except genesis and timestamp) can also be passed as flags to configure the environment completely in the command line. For example, the following command forks Phron at block 100.

npx @acala-network/chopsticks@latest --endpoint wss://testnet.phron.ai --block 100

Quickstart

The simplest way to fork Phron is through the configuration files that are stored in the Chopsticks GitHub repository:

npx @acala-network/chopsticks@latest \
--config=https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/phron.yml

Interacting with a Fork

When running a fork, by default it will be accessible at:

ws://localhost:8000

You will be able to interact with the parachain via libraries such as Polkadot.js and its user interface, Polkadot.js Apps.

You can interact with Chopsticks via the Polkadot.js Apps hosted user interface. To do so, visit the page and take the following steps:

  1. Click the PhronesisTelem in the top left

  2. Go to the bottom and open Development

  3. Select the Custom endpoint and enter ws://localhost:8000

  4. Click the Switch button

You should now be able to interact with the fork as you would an active parachain or relay chain.

Note!

If your browser cannot connect to the WebSocket endpoint provided by Chopsticks, you might need to allow insecure connections for the Polkadot.js Apps URL. Another solution is to run the Docker version of Polkadot.js Apps.

Replaying Blocks

In the case where you would like to replay a block and retrieve its information to dissect the effects of an extrinsic, you can use the npx @acala-network/chopsticks@latest run-block command. Its following flags are:

FlagDescription

endpoint

The endpoint of the parachain to fork.

block

Use to specify at which block hash or number to replay the fork.

wasm-override

Path of the WASM to use as the parachain runtime, instead of an endpoint's runtime.

db

Path to the name of the file that stores or will store the parachain's database.

config

Path or URL of the config file.

output-path=/[file_path]

Use to print out results to a JSON file instead of printing it out in the console.

html

Include to generate an HTML representation of the storage diff preview between blocks.

open

Whether to open the HTML representation.

For example, running the following command will re-run Phron's block 1000, and write the storage diff and other data in a phron-output.json file:

npx @acala-network/chopsticks@latest run-block  \
--endpoint wss://testnet.phron.ai  \
--output-path=./phron-output.json  \
--block 1000

WebSocket Commands

Chopsticks' internal websocket server has special endpoints that allows the manipulation of the local Substrate chain. These are the methods that can be invoked:

MethodParametersDescription

dev_newBlock

options

Generates one or more new blocks.

dev_setStorage

values, blockHash

Create or overwrite the value of any storage.

dev_timeTravel

date

Sets the timestamp of the block to the date value.

dev_setHead

hashOrNumber

Sets the head of the blockchain to a specific hash or number.

The parameters above are formatted in the following ways:

ParameterFormatExample

options

{ "to": number, "count": number }

{ "count": 5 }

values

Object

{ "Sudo": { "Key": "0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b" } }

blockHash

string

"0x1a34506b33e918a0106b100db027425a83681e2332fe311ee99d6156d2a91697"

date

Date

"2030-08-15T00:00:00"

hashOrNumber

number | string

  • options { "to": number, "count": number } - a JSON object where "to" will create blocks up to a certain value, and "count" will increase by a certain number of blocks. Use only one entry at a time within the JSON object

  • values Object - a JSON object resembling the path to a storage value, similar to what you would retrieve via Polkadot.js

  • blockHash string - optional, the blockhash at which the storage value is changed

  • date Date - a Date string (compatible with the JavaScript Date library) that will change the time stamp from which the next blocks being created will be at. All future blocks will be sequentially after that point in time

  • hashOrNumber number | string - if found, the chain head will be set to the block with the block number or block hash of this value

Each method can be invoked by connecting to the websocket (ws://localhost:8000 by default) and sending the data and parameters in the following format. Replace METHOD_NAME with the name of the method, and replace or delete PARAMETER_1 and PARAMETER_2 with the parameter data relevant to the method:

{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "METHOD_NAME",
    "params": ["PARAMETER_1", "PARAMETER_2", "..."]
}

This tutorial is for educational purposes only. As such, any contracts or code created in this tutorial should not be used in production.The information presented herein has been provided by third parties and is made available solely for general information purposes. Phron does not endorse any project listed and described on the Phron Doc Website (https://docs.Phron.ai/). Phron does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Phron disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Phron. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Phron has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Phron harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.

Last updated