Skip to main content

Report for Redspot v0.1

Proposal overview#

Patract Labs (https://patract.network) provides solutions for Polkadot's parachain smart contract ecosystem. Three weeks ago, we applied a treasury proposal for Redspot v0.1. Here is a youtube video for overall demonstration. Now, we have finished all the features on time. We ask the councillors to check our work and give feedbacks. Welcome to our riot room to talk about smart contract development.

Redspot is inspired by Ethereum's Truffle. Redspot is a 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 is in https://github.com/patractlabs/redspot.

Jupiter is a long term Substrate testnet, dedicated in Wasm smart contract development. We also host a public node in develop mode for deploying and testing smart contract. The source code is in https://github.com/patractlabs/jupiter.

Redspot v0.1 introduction#

Except the requirements in the proposal, we have provided an objectified way to operate with contracts, which has not been implemented in Polkadot-js SDK yet. For more information, please check out contractApi. Most of the requirements are finished, expect some issues because ink! is a little unstable.

Redspot's migration and test can be used just like web3.js. Developer can write scripts like this rather than using raw call to build raw extrinsic or RPC parameters.

// contractApi can be obtained by contract.load and contract.deployed, it can call the methods of the contract.// It calls the balanceOf method of the contract and returns the corresponding type by rpc.contractApi.messages.balanceOf(Alice.publicKey).call(<option>) // It sends a contract transfer to the chain and get a Result type.contractApi.messages.transfer(Bob.publicKey, '100000').send(<option>) 

And then, We will show you the details about how Redspot works:

how Redspot works

Currently, Redspot only support macOS and Linux, without Windows (waiting for ink! to support).

Using Redspot on your computer#

Now, let's assume that you are a new developer for pallet-contracts. You know nothing about Substrate, hasn't prepared the developing environment for contracts. But, you had read some guides or cookbooks, and known a little about ink!. Then, you try to write Wasm contracts for pallet-contracts.

Just follow us to use Redspot and build your own contracts!

  1. You do not need to clone Redspot project, just need to check whether there is a npx command on your machine.

    npx is a package running tool that comes with npm 5.2+ and higher, it ensures that you always install the latest version.

    if you don't have npx command, just do npm install -g npx

    If you have installed npx, you must already have npm, or you could install yarn command, which is also what we recommend to use.

  2. Install and use Redspot to pull a contract project template

    npx redspot-new \<app-name> --template \<template-name>

    npx would automatically download the newest redspot-now on your machine, and could use it in any place. So, you do not need to compile or build Redspot project.

    For example, if you want to create a contract project named myerc20 and use the erc20 template as initial contract project framework, you could use the following command:

    npx redspot-new myerc20 --template erc20

    If you don't add --template, Redspot would use flipper as default template.

    Awesome, the myerc20 is your own contract project, you could start developing contracts from now!

    $ npx Redspot-new myerc20 --template erc20npx: installed 43 in 2.664s   ✨  Creating a new Project in /myerc20.Installing packages. This might take a while.yarn add v1.22.5info No lockfile found.[1/4] Resolving packages...# ...Done in 2.80s.   πŸŽ‰  Success! Created myerc20 at /myerc20πŸ‘‰  Inside that directory, you can run several commands to help you develop the contract:     yarn build    Compile the contract.     yarn test    Test the contract.     yarn Migrate    Migrate the contract
  3. Then, there is a template contract project in you current directory.

    The directory structure is similar with the directory that truffle generated, including migartions, tests, Redspot-config.js and so on. But currently, We can't support a contracts directory due to ink!'s limit. After ink! become stable in the future, we will move all the contracts into contracts directory and organise contracts. About more information, please refer to this ink Issue.

    Same with Truffle, the config file Redspot-config.js is the most important file in the project, which would let Redspot to identity the contract project.

  4. Now, lib.rs is your contract file in your directory.

    This file will be changed in the future. You can just write you custom contract logic in it. For more information, please refer to ink!, and we advice new developers to look through all example in ink!.

  5. Compile your contract!

    In the current directory, you could use those commands to compile you contract:

    npm run build# or yarn build

    That means you could use npm run or yarn to do the same operation. Later, we will use yarn to represent all cases for npm run

    However you may haven't installed contract compile toolchain, then you would get:

    $ npm run build   > myerc20@0.1.0 build /myerc20> Redspot build   /bin/sh: 1: cargo: not foundERROR: No `cargo-contract` foundRun the following command to install it:$ cargo install --git https://github.com/paritytech/cargo-contract cargo-contract --forcenpm ERR! code ELIFECYCLEnpm ERR! errno 1npm ERR! myerc20@0.1.0 build: `Redspot build`npm ERR! Exit status 1npm ERR! npm ERR! Failed at the myerc20@0.1.0 build script.npm ERR! This is probably not a problem with npm. There is likely additional logging output above.   npm ERR! A complete log of this run can be found in:npm ERR!     /root/.npm/_logs/2020-09-11T10_03_43_152Z-debug.log

    Currently we just print some errors to advice developers to download toolchain, because ink! and cargo-contract is not stable now. In the future, we would automatically download all toolchains and install them, without bothering developers.

    After installing all toolchains, you could continue following steps.

    If compilation is done, you could get the artifacts in artifacts directory.

    $ yarn buildyarn run v1.22.4$ Redspot build✨  Detect contracts: erc20(/.../.../myerc20/Cargo.toml)   ===== Compile erc20 =====   cargo +nightly contract build [1/3] Building cargo project   Compiling serde_derive v1.0.116# ...   Compiling erc20 v2.1.0 (/tmp/cargo-contract_OOAxF6)    Finished release [optimized] target(s) in 14.86s [2/3] Post processing wasm file [3/3] Optimizing wasm file Original wasm size: 59.8K, Optimized: 37.6K   Your contract is ready. You can find it here:/.../.../erc20/target/erc20.wasm   ===== Generate metadata erc20 =====   cargo +nightly contract generate-metadata  Generating metadata [1/3] Building cargo project    Finished release [optimized] target(s) in 0.03s [2/3] Post processing wasm file [3/3] Optimizing wasm file Original wasm size: 59.8K, Optimized: 37.6K    Updating git repository `https://github.com/paritytech/ink`    Updating crates.io index   Compiling serde v1.0.116# ...   Compiling metadata-gen v0.1.0 (/tmp/cargo-contract_VQK5N3/.ink/metadata_gen)    Finished release [optimized] target(s) in 21.21s     Running `target/release/metadata-gen`        Your metadata file is ready.You can find it here:/.../.../myerc20/target/metadata.json   🚚  Copy wasm files: erc20.wasm🚚  Copy abi files: metadata.jsonπŸŽ‰  Compile successfully! You can find them at /.../.../myerc20/artifacts   Done in 59.94s.

    In our case, the artifacts directory contains:

    artifacts    |- erc20.json    |- erc20.wasm
  6. Deploy your contracts.

    After development, it's time to deploy you contracts. But before your deployment, please checkout Redspot-config.js.

    module.exports = {  outDir: './artifacts',  networks: {      // this is the network config, same to truffle, the migaration/test command would connect network dependent on this config.    development: {        // `types` is related to connected chain, this is important for polkadot.js      types: {         Address: "AccountId",        LookupSource: "AccountId",      },        //`prefix` is the ss58check Version for chain address, this would affect the scripts in migrations/tests      prefix: 42,       endpoints: ['ws://127.0.0.1:9944'], // please check endpoints, it's the websocket address for blockchain        // accounts is the key pair for migrations/tests      accounts: [        {          name: 'alice',          publicKey: '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d',          secretKey: '0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011',        },        // ...      ],    },  },};

networks is as same as Truffle, will be used when set --network parameter for migaration/test commands.

However, developers should be concerned with types and prefix. Those two parts are related to the connected blockchain. For example, If you want to connect with polkadot mainnet work, you should set types as {} and set prefix as 1 . If you want to connect with a custom Substrate blockchain, I should set types and prefix to matching value. For the types, please refer to this link.

We recommend developers to use "Jupiter" as the testnet, because Jupiter contains a node in develop mode, which doesn't need interval time to produce blocks. This feature will save lot of time for developing contracts.

Note: if you use Jupiter as the testnet, please make sure the types is the correct json.

If we assume the node is running on your machine, now you could deploy the myerc20 contract by doing yarn migarate:

$ yarn migrateyarn run v1.22.4$ Redspot migrateπŸ‘‰  Running migration: 1_deploy_contracts.js
===== PutCode erc20 =====WasmCode: 0x0061736d01000000015f1060027f7f......000006000000070041b080040b0102➀ erc20 codeHash: 0x9e05d9d5119b97343e69ed8ca68182639242c278ba04a753c36eeb44ba760fb1
===== Instantiate erc20 =====Endowment:   50000000000GasRequired: 100000000000CodeHash:    0x9e05d9d5119b97343e69ed8ca68182639242c278ba04a753c36eeb44ba760fb1InputData:   80,65,230,145,252,0,0,100,167,179,182,224,13,0,0,0,0,0,0,0,0➀ erc20 contract address: 5D2z2wBACmwVCFBzSGjWbEhtQnxQuFiJNXoEJZeMyzeDd1rkDone in 1.73s.

Please notice that this command would automatically find the Wasm file in artifacts directory, find the deploy script in migarations directory, and executive it. The node where the Wasm would be deployed is the endpoint in Redspot-config.js file.

  1. Test your contracts.

    The most important thing in contract development is testing. ink! has already provided a way to write unit case to test contracts. However, simple unit test can't cover many complex situations, like multiple contracts project, the contracts related to block height, and so on. Thus, there must be a way for integration testing.

    yarn test is the command for contract integration test. It would execute all scripts in tests directory.

    Please notice that the default logic for contract address determiner is currently dependent on code_hash, data_hash and origin (refer to SimpleAddressDeterminer), so that using same code and same init data from same sender could only instantiate once for a contract, so that the testing scripts should be careful to handle instantiate(meaning deploy a contract) , like using different sender in different tests or using same deployed contract address when the contract could call more than once.

    Redspot hasn't implemented the same feature yet, which is like migration.sol in truffle, so Redspot can't automatically distinguish whether current contract has already been deployed. In the future, we would support this feature to help testing and instantiating (deploying).

    But now, if the tests are not complex, developers could start blockchain node using --tmp parameter. This parameter would start new chain without old data, thus developers could restart the blockchain node each time when they test.

  2. objectified way to operate contracts

    Developer could use an objectified way to operate contracts in migarate and test scripts. In the future, this feature could be used in interactive console. Currently, we show an example like this:

// load contractApi from artifacts, this would auto parse information from contract abi fileconst erc20 = artifacts.require('erc20');test('contract test', async () => {  const Alice = config.pairs[0];  const Bob = config.pairs[1];  // call put_code in low level (note currently if upload same code would not cause extrinsic failed)  const code_hash = await erc20.putCode(Alice);  const erc20Api = await erc20.deployed(    Alice,    code_hash,    erc20.abi.constructors[0]('1000000000000000016'), // instantiate parameters     "50000000000", // endowment    "100000000000"  // gas limit  );      // call rpc `call` to run contracts and get value  const totalSupply = await erc20Api.messages.totalSupply().call();  // create an extrinsic and wait to block to pack and return the result of extrinsic result.  const transferResult = await erc20Api.messages.transfer(Bob.publicKey, '100000').send({    from: Alice,    gasLimit:"100000000000",  });}

From the example, we could see that developers do not need to care about how to parse ABI files and build call parameters, just operate a contract like an object.

What we have done in this version#

As we described above, we have implemented all features required in the proposal. Except some issues due to the unstable ink!. Redspot could achieve a basic contract developing framework like how Truffle does in Ethereum. Maybe some features need to be improved. But currently, Redspot is a complete tool framework which could help developers to improve developing process for contracts.

We hope all contract developers could benefit from Redspot!

What features we will add in the next proposals#

We will apply a new detailed proposal for Redspot v0.2. Briefly, we will add a migrations framework to control whether a contracts has beed deployed. We will find a way to solve repeat instantiate and do not need to restart the blockchain. We will provide an interactive console for directly interact with contract.

We will apply a new detailed proposal for Europa v0.1 (firstly introduced in Post #15). Europa is a sandbox of Substrate runtime environment, which would be used to simplify the developing, debugging, and integration test when developers develop Substrate runtime applications and test pallet-contracts. We will provide an independent runtime execution environment, allowing developers to use some special operation to operate the blockchain, like "jump to height" and "revert to height". We will provide an independent database for blockchain to establish other indexes, like index for extrinics. We will export stored key/value directly.