Patract's Treasury Report for Redspot v0.4 (Wasm contract scaffold)

3yrs ago
2 Comments

10 months ago, we submitted the Treasury Proposal #0 for Redspot v0.1 and described the development plan for the next 4 versions. A few weeks ago, we submitted the Treasury Proposal #44 for Redspot v0.4, and now we have completed all the plans. Redspot has become a powerful development environment, testing framework and asset pipeline for Pallet-Contracts. Redspot is trying to let the development of ink! be projectized and simplify the testing and interacting with contracts. The source code and docs are at https://github.com/patractlabs/redspot/

Summary of Redspot’s Future Plan:

  • v0.1: Support multi-contract: In the recent updates of ink! and cargo-contracts, multi-contracts can finally be compiled normally. Therefore, Redspot will revise its support system for multiple contracts.
  • v0.2: Support docker compilation: Because of the current different environments, Wasm compilation results will be inconsistent (for example, Substrate's Runtime uses srtool to solve this problem). On the other hand, It may be difficult to build a compilation environment under different operating systems (such as Windows), so supporting docker can solve many environmental problems.
  • v0.3: Support web interface: Although Redspot is basically a command line tool, it is not very attractive to programmers who are just getting started. Therefore, Redspot plans to introduce a contract deployment and operation interface similar to Canvas-UI, and add rich functions to this interface, strengthen the contract-related attributes in product design, and visualize some Redspot functions. And this interface can also add additional functions such as calling the polkadot{.js} extension for transaction signing (the browser extension cannot be called in the Redspot command line).
  • v0.4: Add some other plugins to enrich the Redspot ecosystem, such as support for chain types, plugins for monitoring file changes, and so on.

New features in Redspot v0.4

The core functions of Redspot have been completed in v0.3. In Redspot v0.4, we mainly made some optimizations on the user experience, such as adding docker support, adding a GUI interface, supporting browser extension signatures, and other optimizations. Now let us show the design and implementation of v0.4, as well as how to run and verify it. Like v0.3, you can install a template project locally via npx redspot-new erc20. For specific usage methods, please refer to previous reports or our documents.

Redspot Multi-contracts compilation

The official compilation tool of ink! is cargo-contract and it does not support the compilation of multi-contracts. You need to write additional scripts to fulfill. But in Redspot v0.4, we have implemented multi-contracts compilation very well. It supports automatic detection of contract files and simultaneous compilation of contracts in multiple languages.

For the ink! contract, Redspot will find all cargo.toml files in the configured directory, and then parse the cargo.toml file. If it contains ink_lang dependencies, it will consider this to be an ink! contract. Then you can find all the contracts under the project.

For solang contracts, Redspot can find all contracts by matching .sol files.

The compilation configuration of Redspot's default template contract is as follows:

...

export default {
  ...
  contract: {
    ink: {
      toolchain: "nightly",
      sources: ["contracts/**/*"],
    },
  },
  ...
};

Among them, toolchain represents the toolchain that needs to be used when compiling the contract, and sources represents the directory that needs to be found, and supports glob syntax. At the same time, the sources option can also be specified through the command line, which will override the configuration options in the config file:

npx redspot compile "contracts/**/*"

You can also specify a single directory, this can compile a single contract:

npx redspot compile "contracts/erc20"

Solang is also a similar configuration:

...

export default {
  ...
  contract: {
    ink: {
      toolchain: "nightly",
      sources: ["contracts/**/*"],
    },
    solang: {
      sources: ['contracts/**/*.sol']
    }
  },
  ...
};

Ink! and solang can exist at the same time. Redspot uses cargo-contract for ink! contract and solang compiler to compile solang contract. We will also provide support for other compilers in the future.

All compilation products can be found under artifacts (or a directory configured by the user):

-- artifacts
    -- erc20.contract
    -- erc20.json

redspot will generate a .contract file and a .json file for the same contract. .contract contains all the information of .json, and additionally contains the source code of wasm. So .json is only provided to the front-end and used when the front-end does not need to upload wasm.

Note that the names of multiple contracts in the project should not be the same. redspot will detect this situation and report an error. An example of contract compilation can be found.

Clone the Redspot repository and enter the redspot/examples/multi-contract directory. Then install dependencies:

$ yarn

Then you need to make sure you have installed cargo-contract and solang. redspot will not install them automatically.

Then run the compilation command:

$ npx redspot compile

This will compile all contracts at once, including solang contracts, which can be found under contracts/filpper. The compiled product can be found in the artifacts directory, and then we delete the artifacts folder. Run the command:

$ npx redspot compile contracts/erc20

Can compile erc20 contracts. Check the artifacts folder, only the compiled product of the erc20 contract.

Redspot known types

redspot known types is a plugin that automatically adds types of known chains.

In polkadot, adding types is very troublesome, because they must be added manually instead of automatically generated. And sometimes it is necessary to deal with the compatibility issues of different chain versions.

We hope that users of Redspot can focus on contract development and not care about these details. So we added this plugin, the purpose is to solve the problem of types of different chains.

Most chains have submitted types on Polkadot Apps, and all types are defined in the npm package @polkadot/apps-config. So we will partially quote the types definition in @polkadot/apps-config. But @polkadot/apps-config lacks the types definition of the development environment. Then we will make up this part manually. Currently supported chains are Canvas, Jupiter, Europa, Edgeware, Plasm and Clover.

We have added this plugin to the template by default, and users do not need to perform additional configuration. If you need to add this plugin manually, first install the dependencies:

$ yarn add @redspot/known-types

Then in the redspot.config file, import the plugin:

...import "@redspot/known-types"...export default {  ...};

We can verify through the Jupiter (you can use the online testnet of wss://ws.jupiter-poa.patract.cn/ ) chain. We change the node of the configuration file to connect to Jupiter, and then take care to delete all types:

...
// import "@redspot/known-types"
...
export default {
  ...
  networks: {
    development: {
      endpoint: "wss://ws.jupiter-poa.patract.cn/",
    },
    types: {},
    ...
  }
  ...
};

Then start redspot console:

$ npx redspot console

Then run commands to query the authorities information. Because jupiter's unique type AuthorityState is needed here, and we have not defined the AuthorityState type, so there will be a parsing error:

$ await network.api.isReady;(await network.api.query.poA.authorities("3eTmoLUQtK2dsVFtzLUztfPSd3KghZggMpnz1XdzVt33vK9c")).toHuman()

RPC-CORE: getStorage(key: StorageKey, at?: BlockHash): StorageData:: Unable to decode storage poA.authorities:: createType(AuthorityState):: Cannot construct unknown type AuthorityState
Uncaught:
Error: Unable to decode storage poA.authorities:: createType(AuthorityState):: Cannot construct unknown type AuthorityState

Then we can try to introduce @redspot/known-types to fix this problem

...
import "@redspot/known-types"
...
export default {
  ...
  networks: {
    development: {
      endpoint: "wss://ws.jupiter-poa.patract.cn/",
    },
    types: {},
    ...
  }
  ...
};

Then follow the same steps as before. At this time, because @redspot/known-types will identify the connected chain and inject known type definitions, including the AuthorityState type, it can now be successfully parsed:

$ npx redspot console
> await network.api.isReady;(await network.api.query.poA.authorities("3eTmoLUQtK2dsVFtzLUztfPSd3KghZggMpnz1XdzVt33vK9c")).toHuman()
'Working'
​```

Redspot docker

In Redspot v0.4, we added support for using docker to compile contracts. This will ensure that the wasm compiled under different platforms is consistent.

Redspot will use redspot/contract this docker image to compile and run the testnet. It is modified on the basis of contract docker image provided by Parity Tech.

Currently only supports ink! contract docker compilation, the configuration is as follows:

...

export default {
  ...
  contract: {
    ink: {
      toolchain: "nightly",
      docker: true,
      sources: ["contracts/**/*"],
    },
  },
  ...
  docker: {
    sudo: false,
  },
  ...
};

Before running the compile command, please make sure that docker is installed on this machine. Run command

$ npx redspot compile

⚠️Attention
When using docker to compile, it may be affected by the network environment (such as the need for a vpn proxy in China Mainland), which will cause the compilation time to be long.
If you use ctrl+c to exit the current compilation command in the middle, the docker container will not automatically stop deleting.

Now it will compile with docker by default. If you want to change the default behavior, please add the --docker false parameter:

$ npx redspot compile --docker false

Note that if you encounter permission errors, please change the docker.sudo in the redspot.config file to true. This will use sudo to run docker.

Similarly, you can also use docker to run a testnet. The canvas testnet is currently built in. In the future, we will build more testnets for users to choose from.

The current command to run the testnet is:

$ npx redspot testnet

In fact, its role is just to run the command:

$ docker run -p 9944:9944 --rm redspot/contract /bin/bash -c "canvas --tmp --dev --ws-port=9944 --ws-external"  

If you want to modify the default running command, you can add the command parameter:

$ npx redspot testnet --command 'docker run -p 9945:9944 --rm redspot/contract /bin/bash -c "canvas --tmp --dev --ws-port=9944 --ws-external"'

We will recommend and guide users to give priority to using docker, because this can focus on the writing of contracts and avoid a lot of trouble in environment configuration and node startup.

redspot explorer

We found that most users use @polkadot/apps or Canvas UI to assist in debugging when developing contracts. So we developed redspot explorer based on @polkadot/apps, with the purpose of replacing @polkadot/apps in contract development. For this we have done a lot of modifications and optimizations. And the native code and web page are connected in a certain program. We mainly made these optimizations:

  1. Redesigned the layout and menu to focus more on the contract module. Improved the night mode of polkadot apps, adjusted the UI, and adjusted the color scheme. Delete pages that are useless for contract development. Some tool pages have been merged.

  1. The network configured in redspot config will be injected into explorer.

  2. The account configured in the redspot config will appear in the explorer and can be used in the explorer. For example, you can perform transactions such as transfers, just like the web account.

  3. The types configured in redspot will be adopted by explorer.

  4. The .contract file of the contract generated in the local project will be automatically uploaded to the explorer. The contracts page in the explorer will list all the contracts known to the code.

  5. When switching networks, only the contract and abi and account numbers of the current network are displayed.

  6. You can use polkadot{.js} extension to sign when you run tests or scripts locally.

  7. Able to send instructions to compile code locally in explorer.

  8. You can run redspot scripts in explorer.

  9. If there is a known code, the contract event and the parameters when sending the contract will be automatically parsed in the block details.

  10. You can inquire about transactions related to the contract.

To use redspot explorer, you need to install the @redspot/explorer plugin:

$ yarn add @redspot/explorer

Then add below in redspot.config:

...
import "@redspot/explorer";
...

Run redspot explorer:

npx redspot explorer

Note that when running redspot explorer, a service will be started locally, please do not terminate the process. And, please restart the service manually every time when redspot.config is changed.

Then open the default URL http://127.0.0.1:8011

Open switch network

As you can see, you can select the network configured in redspot.

Check the accounts page, the account configured in redspot.config will appear.

Then you can use the account in your polkadot extension to make transactions. Copy your account address in polkadot extension.

Then change the deploy.ts script:

import { network, patract } from "redspot";

const { getContractFactory } = patract;
const {  api } = network;

async function run() {
  await api.isReady;
  const signer = "<your address>";

  const contractFactory = await getContractFactory("erc20", signer);

  const balance = await api.query.system.account(signer);

  console.log("Balance: ", balance.toHuman());

  const contract = await contractFactory.deployed("new", "1000000", {
    gasLimit: "200000000000",
    value: "100000000000",
  });

  await contract.tx.transfer(signer, 7);
  console.log("");
  console.log(
    "Deploy successfully. The contract address: ",
    contract.address.toString()
  );

  api.disconnect();
}

run().catch((err) => {
  console.log(err);
});

Then run the script $ npx redspot run ./scripts/deploy.ts, and then call the polkadot extension for signing. Check the polkadot extension in your browser (note that the explorer page must be open)

Then deploy the contract. Then after the deployment is successful, check the explorer page:

There will be events on the chain. We look at the contracts.instantiateWithCode event,

There will be an analysis of contract message and contract event.

Check the codes page of contracts:

The code of the locally compiled contract will automatically appear here.

Then check the contracts page of contracts:

The contract just deployed will appear here.

Then we switch to the console page, where we can run the script and compile the contract:

We click compile contract and this prompt appears to indicate that the compilation was successful:

If the compilation time is too long, please switch to the terminal running the npx redspot explorer command and check the log prompt.

Then we click run to run the script, and the console on the right will output the run log:

Now that the contract is successful, let's switch to the contracts page to check:

As you can see, the newly deployed contract will appear here.

When we click on the extrinsics button (the blue "extrinsics" in each row in the "recent contracts" in the figure), a dialog box will pop up, showing the relevant transactions of the current contract:

@redspot/decimals

@redspot/decimals is a plug-in that automatically converts the precision of numbers, such as converting 1 DOT to 10000000000.

Currently, the functions implemented by this plug-in are as follows.

Fixed decimal

  • 1 DOT => 10 ** 10
  • 1 KSM => 10 ** 12

Get the tokenDecimal of the chain automatically

  • 1 UNIT => 10 ** tokenDecimal

Install:

yarn add @redspot/decimals

And add the following statement to your redspot.config.ts:

import '@redspot/decimals'

Use when deploying the contract:

  const contract = await contractFactory.deployed('new', '10000', {
    gasLimit: '400000000000',
    value: '10000 UNIT'
  });

Use in transfer

  import { network } from 'redspot';

  const { api } = network;

  async function run() {
    await api.isReady;

    api.tx.balances.transfer(address, '1 UNIT')
  }

This is because that @polkadot/api implements its own set of type system. Therefore, we have rewritten Weight and Balance to recognize functions similar to 1 DOT. If the function used is not the type of Weight and Balance, the above method will not take effect.

How to verify v0.4: Github library

  • Multi-contract support: able to compile the delegator contract in ink/example and the multi-contracts contract project provided by redspot
    • Currently we support mixed compilation of any number of ink! contracts and solang contracts. Just set the directory that needs to be compiled.
  • Support docker compilation: redspot can automatically pull and run the docker image containing cargo-contract component under the user's choice to compile the contract. The compiled structure can be moved to the artifacts directory, and the file permissions are correct.
    • We created a docker image to compile the contract and start the testnet.. And integrated into redspot.
  • Redspot's web interface:
    use @redspot/explorer plug-in
    • Display the information and contract interface of the connected node
      • redspot explorer can display the network configured in redspot. The contract abi file in the local directory is automatically uploaded. Will show all contracts associated with the current abi file
    • When a contract is deployed, the contract information and related transactions will be recorded. And can be associated with the deployer. For Europa, it can directly scan the deployed contracts and associate relevant information.
      • The redspot explorer can query transactions related to the current contract (similar to polkadot apps explorer). For europa, redspot will scan all blocks.
    • Display detailed contract operation information
      • In the redspot explorer, the message and event information of all contracts that can be queried for abi will be automatically parsed. It can be viewed in the block details.
    • The information that Redspot originally displayed on the command line can be displayed in the web interface, and redspot test cases can be called and executed from the web interface.
      • A console function is provided in redspot explorer, which can send the code for local execution. And we also added a button to compile the contract. Allows users to execute compilation commands directly on redspot explorer.
    • Able to call the polkadot.js extension to sign Redspot transactions.
      • When the redspot explorer service is enabled, when a signature is required locally, the polkadot extensions can be accessed indirectly through the redspot explorer gui. So as to realize this function.
  • Other plug-ins
    • redspot-watcher: When the file is not edited, the contract will not be compiled if the relevant commands are re-executed. When the file is compiled, the compilation process will be called when re-executed
      • Use the @redspot/watcher plugin to save the rust and toml file information. If there is no change, the default compilation will be skipped when the test run console command is executed.
    • default blockchain types: Connect Canvas-node and Jupiter. You no longer need to fill in types and you can send transactions normally.
      • We currently add types for Europa, Jupiter, Canvas, Edgeware, Plasm, Clover, etc. There is no need to manually configure types when using these chains. Among them, Canvas, Edgeware, Plasm, and Clover get types through @polkadot/app-config, so the correctness of the types depends on the configuration they submit. For Europa, Jupiter, we maintain the types manually.
    • Balances decimal plug-in: Use canvas, Jupiter and Europa to test, respectively test 1 Unit, 1 DOT, etc.
      • Use @redspot/decimals to achieve this function.
Up
Comments
No comments here